C#避免多个SWITCH语句.net

问题描述 投票:8回答:6

当我学习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;
   }
 }
c# .net switch-statement
6个回答
2
投票

也许我不理解这个问题,但是如果你的所有类都具有相同的属性,那么你可以将对象(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;
}

4
投票

既然你正在学习.net / c#,我想我应该警告你,使用静态属性可能不是面向对象编程的方法。

静态是全球状态并且是危险的。如果你最终使用多线程代码,你必须非常小心。如果你只需要一个实例,只需要实例化一个实例,但不要在类上创建静态属性,除非你有充分的理由添加它们(我现在想不到任何东西)。

实际上,在设计良好的面向对象代码中,你可能不应该有很多if,switch,getter或setter。

假设你的课程需要不同的行为,你可以这样做。

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);
  }
}

1
投票

如果您不需要具体的类,您可以像这样抽象逻辑:

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
投票

如果你是解决像this这样的多个开关案例的javascript方式的粉丝

你总是可以将开关处理程序包装为Actions并将它们放入Dictionary中。

例如:(来自here的来源)

   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);

0
投票

下面的代码使用各种黑客,除非你有充分的理由,否则不会在生产代码中真正推荐。

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
投票

您可以使用字典作为配置并删除switch语句创建字典并添加如下所示的附加数据以进行映射

//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!
© www.soinside.com 2019 - 2024. All rights reserved.