2011-04-08 79 views
0

的所有實現我要求一個更加流暢和漂亮的方式(如果我錯了這裏和/或修正)要做到這一點,填寫一個HashSet <T>與ISomething

HashSet<ISomething> itemRows; 

List<ISomething> PopulateItemRows() 
{ 
    itemRows = new HashSet<ISomething>(); 
    itemRows.UnionWith(new SomeType1().Collection()); 
    itemRows.UnionWith(new SomeType2().Collection()); 
    itemRows.UnionWith(new SomeType3().Collection()); 
    itemRows.UnionWith(new SomeType4().Collection()); 
    return itemRows.ToList(); 
} 

SomeTypeXX都實現了ISomething 。

最好的當然是避免顯式包括類型。 可能存在新實現的情況,並且此方法未能更新。

+1

更正1:'PopulateItemRows'預計返回void,但您的返回語句返回一個列表。簽名應該是'公開名單 PopulateItemRows()' – 2011-04-08 07:51:34

+0

當然。由一些編輯引起的。感謝您的糾正。現在,只有一些建議是錯過:)。 – Independent 2011-04-08 07:54:57

回答

2

如果你想有一個通用的方法來找到所有類型的實施ISomething

var somethingTypes = typeof(ISomething) 
    .Assembly 
    .GetTypes() 
    .Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Any(i => i == typeof(ISomething)) 

foreach (var t in somethingTypes) 
{ 
    var o = Activator.CreateInstance(t); 
    var mi = (IEnumerable<ISomething>)t.GetMethod("Collection"); 
    if (mi != null) 
    { 
     var items = .Invoke(o, null); 
     itemRows.UnionWith(items); 
    } 
} 

的代碼假定所有類型的實施ISomething住在同一程序集作爲接口。

更新:新增基於馬丁斯一些健全檢查回答

1

我這個啓動:

... 
List<ISomething> instances = new List<ISomething>({new SomeType1(), new SomeType2(),...}); 
... 
List<ISomething> PopulateItemRows() 
{ 
    itemRows = new HashSet<ISomething>(); 
    foreach(ISomething instance in instances) 
    { 
     itemRows.UnionWith(instance.Collection()); 
    } 
} 
0

我不知道,如果你的代碼是真的很喜歡這一點,因爲ISomething看起來有點怪異。無論如何,這是一個基於反思的解決方案。

interface ISomething { 
    IEnumerable<ISomething> Collection(); 
} 

List<ISomething> PopulateItemRows() { 
    var itemRows = new HashSet<ISomething>(); 
    var constructorInfos = Assembly.GetExecutingAssembly().GetTypes() 
    .Where(
     type => type.IsClass 
     && !type.IsAbstract 
     && typeof(ISomething).IsAssignableFrom(type) 
    ) 
    .Select(type => type.GetConstructor(Type.EmptyTypes)) 
    .Where(ci => ci != null); 
    foreach (var constructorInfo in constructorInfos) { 
    var something = (ISomething) constructorInfo.Invoke(null); 
    itemRows.UnionWith(something.Collection()); 
    } 
} 
+0

ISomething實現的類包含一個構造函數,它執行X Y.實例化後,方法Collection()給出它自己的列表。爲什麼奇怪? – Independent 2011-04-08 08:27:08

+0

「ISomething」的遞歸性質對我來說看起來有點奇怪,但顯然我不知道你是否真的需要遞歸來描述「某些事物」的層次結構。 – 2011-04-08 08:44:45

+0

這實際上是一個CSV文件的解析器,它必須作爲整體進行收集,以便在將其寫回文件時保留父/子項相關結構。 – Independent 2011-04-08 08:53:46

相關問題