2011-04-08 73 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

相关问题