C # Избегайте множественных утверждений переключателя .net - PullRequest
8 голосов
/ 25 марта 2011

Прошу прощения за глупости, когда я изучаю тонкости C # / .NET

Скажем, у меня есть три класса с несколькими статическими свойствами (более трех, но для аргументов ради ..)

 CLASS FOO

    public static A
    { 
       get / set A;
    }   
    public static B
    {
       get / set B;
    }   
    public static C
    {
       get / set C;
    }   

 CLASS BAR
     {
        get / set A;
     }
    public static B
    {
       get / set B;
    }   
    public static C
    {
       get / set C;
     }   

 CLASS YOO
     {
        get / set A;
     }
    public static B
    {
       get / set B;
     }   
    public static C
    { 
       get / set C;
    }   

А из другого класса мне нужно несколько раз обновить одно или несколько статических свойств в каждом классе ... Как мне не писать несколько SWITCH-оценок, подобных этой ...

 public void updateVarx(string class, string varx)
 {
   string y = 'class'
   SWITCH (y)
   {
      case FOO:
       FOO.A = Varx;
       break;
      case BAR:
       BAR.A = Varx;
       break;
      case YOO:
       YOO.A = Varx;
      break;
   }
 }

А потом ещеодин, когда я хочу обновить B varY:

 public void updateVary(string class, string vary)
 {
   string y = 'class'
   SWITCH (y)
   {
     case FOO:
      FOO.B = Vary;
      break;
     case BAR:
      BAR.B = Vary;
      break;
    case YOO:
      YOO.B = Vary;
      break;
   }
 }

Ответы [ 6 ]

4 голосов
/ 25 марта 2011

Так как вы изучаете .net / c #, я должен предупредить вас, что использование статических свойств, вероятно, не самый лучший способ для объектно-ориентированного программирования.

Статика является глобальным состоянием и опасна. Если вы в конечном итоге используете многопоточный код, вы должны быть очень осторожны. Если вам нужен только один экземпляр, просто создайте его экземпляр, но не создавайте статические свойства для класса, если у вас нет достаточно веских причин для их добавления (а я сейчас не могу придумать ни одного).

На самом деле, в хорошо спроектированном объектно-ориентированном коде у вас, вероятно, не будет много if, switch, getters или setters.

Допустим, вам нужно различное поведение в ваших классах, вы можете сделать это следующим образом.

Interface ISecurity {
  void UpdateVarX(int value);
  void UpdateVarY(int value);
  int GetValueX();
  int GetValueX();
}

class Foo:ISecurity {
  // Implement methods of the interface
}

class Bar:ISecurity {
  // Implement methods of the interface
}

class Yoo:ISecurity {
  // Implement methods of the interface
}

// This class is the class that uses your other classes
class Consumer 
{
  private ISecurity sec;

  public Consumer(ISecurity sec) {
    sec.UpdateVarX(25);
  }
}

Или если, как в вашем примере, все ваши статические классы имеют одинаковые свойства:

public class Settings {
  public int A {get; set;}
  public int B {get; set;}
  public int C {get; set;}
}

public class NeedsToUseOtherClass {
  public NeedsToUseOtherClass() {
    Settings foo = new Settings();
    Settings bar = new Settings();
    Settings yoo = new Settings();

    foo.setA(25);
  }
}
2 голосов
/ 25 марта 2011

Может быть, я не понимаю проблему, но если все ваши классы имеют одинаковые точные свойства, вы можете просто передать объект (FOO, BAR или YOO) в методы UpdateVarx или UpdateVary и просто реализовать интерфейс? Что-то вроде этого:

public class FOO : IHasStatus
{
    public A
    { 
       get / set A;
    }   
    public B
    {
       get / set B;
    }   
    public C
    {
       get / set C;
    }
} 

public void updateVarx(IHasStatus someObject, string varx)
{
    someObject.A = varx;
}
public void updateVary(IHasStatus someObject, string vary)
{
    someObject.B = vary;
}
1 голос
/ 25 марта 2011

Если вам не нужны конкретные классы, вы можете абстрагировать логику следующим образом:

public class Status {
    public string A {
        get; set;
    }

    public string B {
        get; set;
    }

    public string C {
        get; set;
    }
}

public static class StatusManager {
    private static Dictionary<string, Status> statusMap = new Dictionary<string,Status>();

    public static Status GetStatus(string name) {
        Status status;
        if (!statusMap.TryGetValue(name, out status))
            statusMap[name] = status = new Status();
        return status;
    }

    public static void SetStatus(string name, Status status) {
        statusMap[name] = status;
    }

    public static void UpdateVarx(string name, string varx) {
        GetStatus(name).A = varx;
    }

    // ...
}
0 голосов
/ 14 февраля 2019

Вы можете использовать словарь в качестве конфигурации и удалить оператор переключения. Создайте словарь и добавьте данные добавления, как показано ниже для отображения

//Have dictionary setted up
Dictionary<string, dynamic> m_Dictionary = new Dictionary<string, dynamic>();
m_xmlDictionary.Add("classA",FOO);
m_xmlDictionary.Add("classB",BAR);
m_xmlDictionary.Add("classC",BAR);
//Have dictionary setted up


//change the function as below
public void updatevarx(string class, string varx)
{
    m_Dictionary[class].A=varx // Replaced switch statement
}

//while calling use
updatevarx("classC","abc!");// This will assign BAR.A with abc!
0 голосов
/ 25 марта 2011

В приведенном ниже коде используются всевозможные хаки, которые не рекомендуется в производственном коде, если только у вас нет веских причин.

using System;
using System.Linq;

namespace ConsoleApplication1
{
    static class Program
    {
        private static void SetStaticProperty(string className, string propName, string varx)
        {
            //This sucks, I couldnt find the namespace with easily through reflection :(
            string NAMESPACE = "ConsoleApplication1";
            Type t = Type.GetType(NAMESPACE + "." + className);
            t.GetProperties().Where(p => p.Name == propName).First().SetValue(null, varx, null);
        }

        public static void updateVarx(string className, string varx)
        {
            SetStaticProperty(className, "A", varx);
        }

        public static void updateVary(string className, string vary)
        {
            SetStaticProperty(className, "B", vary);
        }

        static void Main(string[] args)
        {
            updateVarx("Foo", "FooAstring");
            updateVarx("Bar", "BarAstring");
            updateVarx("Yod", "YodAstring");
            updateVary("Foo", "FooBstring");
            updateVary("Bar", "BarBstring");
            updateVary("Yod", "YodBstring");

            Console.WriteLine(Foo.A);
            Console.WriteLine(Foo.B);
            Console.WriteLine(Bar.A);
            Console.WriteLine(Bar.B);
            Console.WriteLine(Yod.A);
            Console.WriteLine(Yod.B);
            Console.ReadLine();
        }
    }

    class Foo
    {
        public static string A { get; set; }
        public static string B { get; set; }
        public static string C { get; set; }
    }

    class Bar
    {
        public static string A { get; set; }
        public static string B { get; set; }
        public static string C { get; set; }
    }

    class Yod
    {
        public static string A { get; set; }
        public static string B { get; set; }
        public static string C { get; set; }
    }
}
0 голосов
/ 25 марта 2011

Если вы являетесь поклонником javascript-способа решения нескольких вариантов переключения, например this

, вы всегда можете заключить обработчики переключателей в действия и добавить их в словарь.

Например: (Источник, полученный из здесь )

   public class SwitchCase : Dictionary<string,Action>
    {
        public void Eval(string key)
        {
            if (this.ContainsKey(key))
              this[key]();
            else
             this["default"](); 
        }
    }


    //Now, somewhere else

            var mySwitch = new SwitchCase
            {
                { "case1",  ()=>Console.WriteLine("Case1 is executed") },
                { "case2",  ()=>Console.WriteLine("Case2 is executed") },
                { "case3",  ()=>Console.WriteLine("Case3 is executed") },
                { "case4",  ()=>Console.WriteLine("Case4 is executed") },
                { "default",()=>Console.WriteLine("Default is executed") },
            };

            mySwitch.Eval(c);
...