2013-05-07 176 views
2

我有基於標準抽象類的相關類,它們將從數據表(對於我使用int數組的示例)加載。該類將按類型發起,然後加載該類的具體細節。 Currenlty我正在用switch語句做這件事,但以另一種方式做這件事可能嗎?基於抽象類型創建類

class Program 
{ 
    static void Main(string[] args) 
    { 
     var list = new[] {1, 1, 3, 2, 2, 4}; 
     TypeBase typeClass = null; 
     foreach (var i in list) 
     { 
      switch (i) 
      { 
       case 1: 
        { 
         typeClass = new Type1(); 
         break; 
        } 
       case 2: 
        { 
         typeClass = new Type2(); 
         break; 
        } 
       case 3: 
        { 
         typeClass = new Type3(); 
         break; 
        } 
      } 
     } 
     if (typeClass != null) 
     { 
      typeClass.LoadDetails(); 
     } 
    } 
} 

public class TypeBase 
{ 
    public int Type { get; set; } 
    public virtual void LoadDetails() 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class Type1 : TypeBase 
{ 
    public override void LoadDetails() 
    { 
     // Load type Specific details 
    } 
} 

public class Type2 : TypeBase 
{ 
    public override void LoadDetails() 
    { 
     // Load type Specific details 
    } 
} 

public class Type3 : TypeBase 
{ 
    public override void LoadDetails() 
    { 
     // Load type Specific details 
    } 
} 
+3

您可以使用反射來嘗試解決該類型名稱:'變種類型= Type.GetType(「類型名稱」)'和使用'Activator.CreateInstance(類型)'創建一個實例 – Charleh 2013-05-07 14:46:07

回答

3

有幾種解決方案。

1.創建類型的反射

該解決方案已被奈爾給出。因爲我預計你的類型不會被稱爲Type1,Type2等,我認爲這不適合你。

2.在字典存儲類型與類型

創建的字典將取代你的開關/箱。它包含了您需要創建類型:

Dictionary<int, Type> types = new Dictionary<int, Type> 
{ 
    {1, typeof(Type1)}, 
    {2, typeof(Type2)}, 
    {3, typeof(Type3)} 
}; 

使用它來創建你的類型:

Type type; 
if (types.TryGetValue(i, out type)) 
{ 
    TypeBase typeClass = (TypeBase)Activator.CreateInstance(type); 
    typeClass.LoadDetails(); 
} 

該解決方案比解決方案#1更快,因爲只使用一個「反思」的操作。

3.在字典存儲類型的工廠方法

創建的字典將取代你的開關/箱。它將包含工廠方法:

Dictionary<int, Func<TypeBase>> factories = new Dictionary<int, Func<TypeBase>> 
{ 
    {1,() => new Type1()}, 
    {2,() => new Type2()}, 
    {3,() => new Type3()} 
}; 

使用它來創建你的類型:

Func<TypeBase> factory; 
if (factories.TryGetValue(i, out factory)) 
{ 
    TypeBase typeClass = factory(); 
    typeClass.LoadDetails(); 
} 

該解決方案比解決方案#2快,因爲沒有反射使用。

4.在字典存儲類型的實例

創建的字典將取代你的開關/箱。它將包含你的類型的實例。這種解決方案只有在這些實例是不可變的並且在調用期間不會改變狀態的情況下才有效

Dictionary<int, TypeBase> typeClasses = new Dictionary<int, TypeBase> 
{ 
    {1, new Type1()}, 
    {2, new Type2()}, 
    {3, new Type3()} 
}; 

使用它來創建你的類型:

TypeBase typeClass; 
if (baseClasses.TryGetValue(i, out baseClass)) 
{ 
    typeClass.LoadDetails(); 
} 

該解決方案比解決方案#3更快,因爲沒有實例與每個調用創建。

一些旁註

  • 爲什麼不使用的接口,其中一個成員LoadDetails?在您的示例成員Type從未使用過。
  • 爲什麼不讓TypeBase.LoadDetails成爲抽象方法?
  • 如果您的keys始終爲Int32,並且處於連續範圍內,則可以考慮使用List<T>或甚至是一個數組,該數組將比字典更快。
+0

將看看並創建一個實現使用你的消化看起來非常intresting .. ;-) – 2013-05-14 17:56:02

1

理想情況下,您應該按照工廠方法來滿足這樣的要求。否則,如果你很樂意遵循約定爲你的子類,那麼一個便宜的技巧將如下所示。

using System; 
using System.Runtime.Remoting; 

namespace ConsoleApplication1 
{ 
    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      var list = new[] {1, 1, 3, 2, 2, 4}; 
      TypeBase typeClass = null; 
      foreach (var i in list) 
      { 
       ObjectHandle handle = Activator.CreateInstanceFrom("ConsoleApplication1", string.Format("{0}{1}", "Type", i));//Program- Name of the assembl 
       var typeBase = (TypeBase) handle.Unwrap(); 
       typeBase.Type = i; 
       typeClass.LoadDetails(); 
      } 
     } 
    } 

    public class TypeBase 
    { 
     public int Type { get; set; } 

     public virtual void LoadDetails() 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public class Type1 : TypeBase 
    { 
     public override void LoadDetails() 
     { 
      // Load type Specific details 
     } 
    } 
} 

注:我個人不會遵循這樣的做法,並會更高興的工廠方法或相當數量的開關。這只是閃現一個可能性而已。請相應測試並修改(如果決定遵循)

+0

可以請你解釋關於你的陳述更多一點:理想情況下,你應該按照工廠方法來滿足這樣的要求 – 2013-05-07 16:51:07

+0

工廠方法是一種理想的設計模式。你可以閱讀更多關於它[這裏](http://www.dofactory.com/Patterns/PatternFactory.aspx#_self2)。不要限制自己嘗試搜索更多的工廠方法實現。它的好處是,它爲您提供了更多靜態類型的語言功能,並且沒有運行時異常的空間。這就是爲什麼我比我的上述選秀更喜歡工廠。 – Nair 2013-05-07 17:45:26