2011-03-24 95 views
8

請原諒的愚蠢的陣陣作爲我學習C#的複雜性/ .NETC#避免多次switch語句.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; 
    } 

而且從另一個類,我需要每個班多次更新一個或多個靜態屬性...我應如何從寫多聯開關statments這樣的...

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

然後又是一個,當我想更新乙各不相同:

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; 
    } 
} 
+0

爲什麼他們必須是靜態屬性? – Aliostad 2011-03-24 23:24:40

+3

在這裏嗅到一些東西... – 2011-03-24 23:26:52

+0

因爲我不想要它們的多個實例......但是除此之外,不知道它們是一組固定證券的狀態變量 – CraigJSte 2011-03-24 23:27:24

回答

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; 
} 
+0

@Pete,由Jove我認爲你已經知道了! (額外的信貸 - 誰說這是福爾摩斯)? – CraigJSte 2011-03-25 00:09:06

+0

如果FOO上的屬性是靜態的,則它們不被視爲接口屬性的實現。 – CodeNaked 2011-03-25 00:10:54

+0

@craigjste我希望如此好友。它無法解決問題。 – Pete 2011-03-25 00:11:25

0

如果你是解決多路開關的情況下比如this

的JavaScript的方式風扇可以隨時收官開關處理器作爲操作並在一個詞典中折騰它們。

例如:(從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

嗯,我會考慮這@world,thnx,我會希望得到一個'更簡單'的答案(是的,我打算把它放在引號中),這可能意味着我不聰明,也可能意味着我只是簡單:) – CraigJSte 2011-03-24 23:31:16

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

你是一個編碼狂人...(我的意思是說,在一個很好的方式:)) – CraigJSte 2011-03-24 23:43:34

+0

假設代碼爲你工作是否安全? – Pete 2011-03-24 23:45:49

+0

@Pete - 你問我還是@CraigJSte? :-) – CodeNaked 2011-03-24 23:48:34

4

既然你正在學習.net/c#,我想我應該警告你,使用靜態屬性可能不是面向對象編程的方式。

Static是全局狀態,很危險。如果最終使用多線程代碼,則必須非常小心。如果只需要一個實例,只需實例化一個實例,但不要在類上創建靜態屬性,除非您有足夠的理由添加它們(而現在我想不出任何)。事實上,在設計良好的面向對象代碼中,如果你使用開關,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); 
    } 
} 
+0

你是什麼意思「在設計良好,面向對象的代碼中,你可能不會有很多if,switch,getters或setters?」 – 2011-03-24 23:55:17

+0

對你有疑問... @Martin ...'只實例化一個' - 如果我在類的頂部實例化,是否意味着它只能執行一次? – CraigJSte 2011-03-24 23:56:04

+0

@Josh M.對於吸氣和吸氣者來說,如果你有他們,這意味着你暴露了你的對象的內部狀態,而不是在你的對象上有行爲,這意味着你的對象的消費者知道的比他們知道的要多。對於switch和ifs,如果你有一個類型檢查(typeof),你的代碼有問題。檢查http://www.antiifcampaign.com/瞭解更多詳情 – Martin 2011-03-24 23:59:45

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

任何理由downvote?我在頂部警告說這不是一個偉大的代碼段,我顯示一個可能性 – 2011-03-25 00:12:32

+0

對不起,但我不得不downvote。這是不正確的方式來解決你說你自己的問題「不真正推薦在生產代碼」 – bic 2011-03-25 00:12:48

+0

是啊這就是我說的。我認爲這項技術仍然在許多這是一種展示可能性的方式 – 2011-03-25 00:14:10