我要求一个更顺畅和更好的方法来做这个(和/或更正,如果我在这里错了),
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。
最好的当然是避免明确包括类型。 可能存在新实现的情况,并且此方法无法更新。
答案 0 :(得分: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
的所有类型都与接口位于同一个程序集中。
更新:根据Martins回答添加了一些健全性检查
答案 1 :(得分: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());
}
}
答案 2 :(得分: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());
}
}