2014-08-28 20 views
0

我搜索了互聯網,試圖找到解決此問題的方案。讀了很多關於單身人士和這樣的模式,但我無法找到一個很好的解決我的特定問題(即使我認爲這是一個非常簡單的問題)。如何將項目中的所有課程添加到列表中

我得到了很多派生類的解決方案。我想要的是有一個列表/容器/我可以引用/訪問/從其中包含我的解決方案中的每個類的對象。

因此,像這樣:

public class Main 
{ 
    public static List<Operation> classList; 
    public Main() 
    { 
     initialize(); 
    } 

    public void initialize() 
    { 
     classList = new List<Operation>(); 
     Operation operation1 = new operation1(); 
     Operation operation2 = new operation2(); 
     classList.Add(operation1); 
     classList.Add(operation2); 
    } 
} 

操作類是從主要的。

Operation1和Operation2類是從Operation類派生的。

UPDATE:

我想以後是這樣的:

classList[].callMethodFromClass or classList("operation1").callMethodFromClass 
+3

請問 - 爲什麼你需要這樣的容器?它的目的是什麼? – 2014-08-28 12:00:23

+1

您可以使用反射來查找輸出目錄中所有DLL中的所有類的類型。您也可以使用反射來實例化每種類型的對象。這是你想要做的嗎? – demoncodemonkey 2014-08-28 12:02:37

+0

你從哪裏得到錯誤? – faby 2014-08-28 12:03:46

回答

1

這會發現在裝配從運營中獲得的所有類型。不過,解決方案可以包含1個以上的程序集。

Type baseType = typeof(Operation); 
foreach (var type in typeof(Main).Assembly.GetTypes() 
    .Where(type => baseType.IsAssignableFrom(type))) { 
     classList.Add(type); 
} 

編輯:我忘了添加這些類型的實例,而不是類型本身。 所以你需要使用

classList.Add((Operation)Activator.CreateInstance(type)); 

改爲。

+0

在foreach語句中獲取錯誤: mscorlib.dll中發生未處理的類型爲「System.StackOverflowException」的異常 – 2014-08-28 12:28:35

+0

發現問題!我在構造函數中啓動initialize(),並且每次讀取它再次調用構造函數的方法。所以遞歸地調用它自己。我應該在哪裏運行初始化方法? – 2014-08-28 13:32:10

2

你需要爲此反思:

IEnumerable<Type> derivedTypes = Assembly 
    .GetAssembly(typeof(Operation)) 
    .GetTypes() 
    .Where(type => typeof(Operation).IsAssignableFrom(type)); 

然後,對於每種類型,您可以創建使用Activator一個實例:

Operation operation = (Operation)Activator.CreateInstance(type); 

上面的代碼假定所有派生類型駐留在與您的Operation類相同的程序集。如果它們分佈在多個組件中,那麼您需要爲每個組件重複上述過程。另請注意,操作類型本身將包含在類型集合中。如果這是一個問題,那麼你需要特別檢查它。

請注意,上述Activator代碼僅適用於具有不帶任何參數的構造函數的類。如果你有任何不適合這種模式的類,那麼事情會變得更加複雜。 CreateInstance有一個重載,它需要將一個對象數組用作構造函數參數,但問題在於確定這些參數應該是什麼。這將需要一些關於你正在處理的具體課程的知識。換句話說,您需要添加一個檢查來確保某個類不會意外地破壞您的代碼,並且您希望要求所有類都具有符合某個標準的構造函數(例如no參數)。

+0

至於他們現在都在同一個大會。當我說這些實例是在運行時創建的時候,我是對的嗎?我想在編譯時從實例中調用一個方法。 但是沒有一個構造函數有任何參數。 – 2014-08-28 12:22:15

+0

實例將在運行時創建,是的。如果你想在編譯時做這樣的事情......也許是即將推出的Roslyn,或者使用像PostSharp或Fody這樣的IL編織工具。或者也許用T4,但這聽起來像是一個拙劣的解決方案。 ;)但是爲什麼你想在編譯時調用方法?生成代碼? – 2014-08-28 12:40:59

+0

在IEnumerable 行上獲取錯誤: 在mscorlib.dll中發生未處理的類型爲「System.StackOverflowException」的異常 當我再次考慮時,實際上我不確定是否需要在編譯時調用這些方法。無論如何,解決這個錯誤可能會使我找到解決問題的辦法。 – 2014-08-28 12:41:07

相關問題