2008-10-28 48 views
2

下面的代碼是我想要根據另一個類的類型返回派生類的更優雅的方式。基於Typeof的工廠或是

  if (option_ is Rectangle) 
      { 
       modelInputs = new Foo(); 
      } 
      else if (option_ is Circle) 
      { 
       modelInputs = new Bar(); 
      } 
      else if (option_ is Triangle) 
      { 
       modelInputs = new Bar2(); 
      } 

回答

7

有無矩形,圓形和三角形實施IHasModelInput:

interface IHasModelInput 
{ 
    IModelInput GetModelInput(); 
} 

那麼你可以做

IModelInput modelInputs = option_.GetModelInput(); 
0

如果允許,您可以將一個類型與「option_」關聯起來,然後創建一個實例。

3

我的看法:你的 「不雅」 的方式是好的。它很簡單,可讀並且完成這項工作。

列有矩形,圓形和三角形通過 IHasModelInput實施必要的工廠函數會工作,但它有一個設計成本:現在你已經加上這組類與IModelInput組類(美孚,酒吧和BAR2)。他們可能在兩個完全不同的圖書館,也許他們不應該彼此瞭解。

更復雜的方法如下。它爲您提供了在運行時配置工廠邏輯的優勢。

public static class FactoryMethod<T> where T : IModelInput, new() 
    { 
     public static IModelInput Create() 
     { 
      return new T(); 
     } 
    } 

    delegate IModelInput ModelInputCreateFunction(); 

    IModelInput CreateIModelInput(object item) 
    { 

     Dictionary<Type, ModelInputCreateFunction> factory = new Dictionary<Type, ModelInputCreateFunction>(); 


     factory.Add(typeof(Rectangle), FactoryMethod<Foo>.Create); 
     factory.Add(typeof(Circle), FactoryMethod<Bar>.Create); 
     // Add more type mappings here 




     IModelInput modelInput; 
     foreach (Type t in factory.Keys) 
     { 
      if (item.GetType().IsSubclassOf(t) || item.GetType().Equals(t)) 
      { 
       modelInput = factory[t].Invoke(); 
       break; 
      } 
     } 
     return modelInput; 
    } 

但是後來問一個問題:你寧願看哪一個?

+0

我同意耦合矩形,圓形等設置的類模型輸入是沒有那麼大。在這些情況下,我通常只是輸入輸入類型的字典來輸出類型,並使用Activator.CreateInstance。 – 2008-10-28 04:10:30

1

你可以把輸入和輸出在一個Hashtable,或存儲它創建創建類的每一個內每個類的類型,然後使用Activator.CreateInstance做factoryin':

Hashtable ht = new Hashtable(); 
ht.Add(typeof(Rectangle), typeof(Bar)); 
ht.Add(typeof(Square), typeof(Bar2)); 

modelInputs = Activator.CreateInstance(ht[option.GetType()]); 

無論哪種方式,Activator.CreateInstance是使工廠在.NET中工作的一種非常酷的方式。享受,並使用我明智地給你的力量,兒子。

0

當我想在運行時將字符串轉換爲類型時,我通常使用這樣的工廠方法,我使用將字符串映射到類型的字典。

像這從最近的一個項目:

public class TaskFactory 
{ 
    private Dictionary<String, Type> _taskTypes = new Dictionary<String, Type>(); 

    public TaskFactory() 
    { 
     // Preload the Task Types into a dictionary so we can look them up later 
     foreach (Type type in typeof(TaskFactory).Assembly.GetTypes()) 
     { 
      if (type.IsSubclassOf(typeof(CCTask))) 
      { 
       _taskTypes[type.Name.ToLower()] = type; 
      } 
     } 
    } 

    public CCTask CreateTask(XmlElement task) 
    { 
     if (task != null) 
     { 
      string taskName = task.Name; 
      taskName = taskName.ToLower() + "task"; 

      // If the Type information is in our Dictionary, instantiate a new instance of that task 
      Type taskType; 
      if (_taskTypes.TryGetValue(taskName, out taskType)) 
      { 
       return (CCTask)Activator.CreateInstance(taskType, task); 
      } 
      else 
      { 
       throw new ArgumentException("Unrecognized Task:" + task.Name); 
      }        
     } 
     else 
     { 
      return null; 
     } 
    } 
}