2016-01-23 64 views
0

考慮我有這些類發現它具有一個特定的屬性值

class BaseClass 
{ 
    public int Variable {get; set;} 
} 
class Class1:BaseClass 
{ 
    public Class1() 
    { 
     Variable=1; 
    } 
} 
class Class2:BaseClass 
{ 
    public Class2() 
    { 
     Variable=2; 
    } 
} 

在另一個地方的一類我想這樣做:

public BaseClass MyMethod(int i) 
{ 
    //I want if i is 1 this method returns Class1 
    //And if i is 2 this method returns Class2. 
} 

一個解決方案是使用switch聲明。但是我的命名空間有很多類,使用switch會產生很多代碼行。

+0

您可以使用反射來做到這一點,但這將會是很多工作,因爲您必須解析方法體並且可能容易出錯。你有沒有考慮使用自定義屬性?就像'[Identifier(1)]'很容易實現。 – thehennyy

+0

您是否需要每次創建新課程,或者您可以多次使用現有課程? – csharpfolk

回答

2

您的評論「但我的命名空間有很多類,並使用開關結果很多代碼行。」告訴我你做錯了什麼。

這是經典的問題,很容易被工廠模式解決,使用開關將是最好的解決方案:

switch(num) { 
    case 1: return new Class1(); 
    case 2: return new Class2(); 
    default: throw new ArgumentException(); 
} 

也許你應該分裂您的命名空間?

與其他解決方案是一個有點難看,因爲你將失去編譯時檢查,是用激活:

return (BaseClass)Activator.CreateInstance("AssemblyName", "Class" + num) 

基於評論,100類和必須選擇一個。

public static class AmazingFactory { 
    private static IDictionary<int, Type> _num2Type; 

    private static void InitializeFactory() { 
     var type = typeof(BaseClass); 

     // get all subclasses of BaseClass 
     var types = AppDomain.CurrentDomain.GetAssemblies() 
      .SelectMany(s => s.GetTypes()) 
      .Where(p => type.IsAssignableFrom(p)); 

     foreach(var type in types) { 
      int numberAtTheEnd = int.Parse(Regex.Match(type.Name, @"\d+$").Value); 
      _num2Type[numberAtTheEnd] = type; 
     } 

    } 

    public static BaseClass Create(int num) { 
     if (_num2Type == null) 
      InitializeFactory(); 

     return (BaseClass)Activator.CreateInstance(_num2Type[num]); 
    } 
} 
+0

我有大約100個班級,每次我寫一個新班級時,我都要編輯switch語句。這是我的問題。 – mohammad

+0

@mohammad - 在你的情況下,也許你應該考慮使用DI容器,比如Castle.Windsor – csharpfolk

0

看起來你不想返回一個類,而是返回一個類的實例。接下來的問題是你想從哪裏得到你的對象?如果它們被存儲在收集一些像

items = new List<BaseClass>(); 
items.add(new Class1()); 
items.add(new Class2()); 

那麼你可以寫類似

public BaseClass MyMethod(int i) 
{ 
    return items.First(item=>item.Variable == i); 
} 

如果你想創建每次調用MyMethod一個新的實例比你將不得不使用switch\if(或者使用Reflection,但這不是推薦的方法)

相關問題