2012-03-13 61 views
0

調用一個方法,我得到了我實現接口的所有類。我想調用一個方法創建如何使用反射

var types =AppDomain.CurrentDomain.GetAssemblies().ToList() 
      .SelectMany(s => s.GetTypes()) 
      .Where(t => typeof(IManagerReport).IsAssignableFrom(t)); 

Console.WriteLine("Processing manager reports.."); 
foreach(var TheType in types) 
{ 
       //error here 
    var temptype = Activator.CreateInstance(TheType) as IManagerReport; 

    temptype.Load(); 
    temptype.Save(); 
    Console.WriteLine("Saved to: " + temptype.SavePath); 
} 

所產生錯誤的對象的實例時,是在這裏:

無法創建接口的實例

+1

東西這在上'.SelectMany'和'.Where'之間的新行:'。凡(T!=> t.IsInterface)',看看有沒有什麼幫助。 – 2012-03-13 17:47:33

+0

的標題有誤導之嫌,你的問題無關,與調用方法,它的一切做的事實,你想構建一個接口的實例。 – 2012-03-13 17:48:23

+0

對不起,如果你喜歡,你可以改變標題。不知道這個叫 – Luke101 2012-03-13 17:50:24

回答

4

確保您從所選取的類型中排除IManagerReport。

var types =AppDomain.CurrentDomain.GetAssemblies().ToList() 
      .SelectMany(s => s.GetTypes()) 
      .Where(t => typeof(IManagerReport).IsAssignableFrom(t) 
         && typeof(IManagerReport) != t 
         && !t.IsInterface 
         && !t.IsAbstract 
         && !t.IsGenericTypeDefinition); 

的問題是,在你的類型枚舉的,你有不只是派生類型IManagerReport的,也是IManagerReport本身。你不能創建一個接口的實例,只能創建一個類。使用我發佈的代碼排除大多數問題項目,但我仍然會在Activator.CreateInstance上添加try/catch。你可能有派生類型沒有無參數的公共構造函數。這些也會失敗。

包裝在一個try/catch呼叫並繼續。我想說你應該在這裏說明所有的可能性,但其中只有太多。考慮一些,然後也考慮到創建根本不會因爲另一個原因而工作的可能性。

try { 
    var temptype = Activator.CreateInstance(TheType) as IManagerReport; 
} catch { 
    continue; 
} 
+0

完美man..Can't感謝你纔好 – Luke101 2012-03-13 17:58:23

1

的這裏的問題是,你IManagerReport謂語Where匹配,因此將在foreach聲明的一個值。您需要Where子句中篩選出接口以及

var types =AppDomain.CurrentDomain.GetAssemblies().ToList() 
      .SelectMany(s => s.GetTypes()) 
      .Where(t => typeof(IManagerReport).IsAssignableFrom(t)); 
      .Where(t => !t.IsInterface && !t.IsAbstract); 
+0

爲什麼使用兩個,語句?這將迭代遍歷枚舉,然後遍歷第二次剩下的內容。這不會像在現有的.Where聲明中那麼簡單&&。 – 2012-03-13 17:53:30

+0

@DavidMorton增加額外的Where子句是不顯著的性能誹謗者。沒有比在環路中使用「if」更好的了。它可以作爲一個「Where」來完成,但我發現它更易於分離不同的謂詞 – JaredPar 2012-03-13 17:54:53

1

嘗試增加或者

.Where(t=>t.IsClass) 

.Where(t=>!t.IsInterface) 

到您的LINQ查詢