C# 填充哈希集<;T>;使用所有的ISomething实现
我要求用一种更平滑、更好的方式来做这件事(和/或纠正我的错误)C# 填充哈希集<;T>;使用所有的ISomething实现,c#,.net,C#,.net,我要求用一种更平滑、更好的方式来做这件事(和/或纠正我的错误) HashSet itemRows; 列表PopulateItemRows() { itemrrows=新的HashSet(); UnionWith(新的SomeType1().Collection()); UnionWith(新的SomeType2().Collection()); UnionWith(新的SomeType3().Collection()); UnionWith(新的SomeType4().Collection())
HashSet itemRows;
列表PopulateItemRows()
{
itemrrows=新的HashSet();
UnionWith(新的SomeType1().Collection());
UnionWith(新的SomeType2().Collection());
UnionWith(新的SomeType3().Collection());
UnionWith(新的SomeType4().Collection());
返回itemrrows.ToList();
}
SomeTypeXX都实现了这一点
最好的方法当然是避免显式地包含类型。
可能会出现新实现的场景,而此方法无法更新。我将从以下内容开始:
...
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());
}
}
。。。
列表实例=新列表({new SomeType1(),new SomeType2(),…});
...
列表PopulateItemRows()
{
itemrrows=新的HashSet();
foreach(实例中的ISomething实例)
{
UnionWith(instance.Collection());
}
}
我首先要说:
...
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());
}
}
。。。
列表实例=新列表({new SomeType1(),new SomeType2(),…});
...
列表PopulateItemRows()
{
itemrrows=新的HashSet();
foreach(实例中的ISomething实例)
{
UnionWith(instance.Collection());
}
}
如果您希望找到实现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);
}
}
var somethingTypes=typeof(ISomething)
装配
.GetTypes()
.Where(t=>t.IsClass&!t.isastract&&t.GetInterfaces().Any(i=>i==typeof(ISomething))
foreach(某些类型的变量t)
{
var o=Activator.CreateInstance(t);
var mi=(IEnumerable)t.GetMethod(“集合”);
如果(mi!=null)
{
var items=.Invoke(o,null);
itemrrows.UnionWith(项目);
}
}
代码假定实现ISomething
的所有类型都与接口位于同一程序集中
更新:添加了一些基于Martins答案的健全性检查如果您想要一种通用方法来查找所有实现
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);
}
}
var somethingTypes=typeof(ISomething)
装配
.GetTypes()
.Where(t=>t.IsClass&!t.isastract&&t.GetInterfaces().Any(i=>i==typeof(ISomething))
foreach(某些类型的变量t)
{
var o=Activator.CreateInstance(t);
var mi=(IEnumerable)t.GetMethod(“集合”);
如果(mi!=null)
{
var items=.Invoke(o,null);
itemrrows.UnionWith(项目);
}
}
代码假定实现ISomething
的所有类型都与接口位于同一程序集中
更新:添加了一些基于Martins答案的健全性检查我不知道您的代码是否真的像这样,因为
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());
}
}
接口{
IEnumerable集合();
}
列表PopulateItemRows(){
var itemRows=newhashset();
var constructorinfo=Assembly.getExecutionGassembly().GetTypes()
.在哪里(
type=>type.IsClass
&&!type.IsAbstract
&&typeof(等轴测)。IsAssignableFrom(类型)
)
.Select(type=>type.GetConstructor(type.EmptyTypes))
。其中(ci=>ci!=null);
foreach(constructorInfo中的var constructorInfo){
var something=(ISomething)constructorInfo.Invoke(null);
UnionWith(something.Collection());
}
}
我不知道你的代码是否真的是这样,因为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());
}
}
接口{
IEnumerable集合();
}
列表PopulateItemRows(){
var itemRows=newhashset();
var constructorinfo=Assembly.getExecutionGassembly().GetTypes()
.在哪里(
type=>type.IsClass
&&!type.IsAbstract
&&typeof(等轴测)。IsAssignableFrom(类型)
)
.Select(type=>type.GetConstructor(type.EmptyTypes))
。其中(ci=>ci!=null);
foreach(constructorInfo中的var constructorInfo){
var something=(ISomething)constructorInfo.Invoke(null);
UnionWith(something.Collection());
}
}
Correction 1:PopulateItemRows
预计将返回void,但您的return语句将返回一个列表。签名应该是public list PopulateItemRows()
当然。这是一些编辑引起的。感谢您的更正。现在,缺少一些建议:).Correction 1:PopulateItemRows
应返回void,但您的return语句返回一个列表。签名当然应该是public list PopulateItemRows()
。这是一些编辑引起的。感谢您的更正。现在,缺少一些建议:).ISomething实现的类包含一个执行X Y的构造函数。实例化后,方法集合()将给出自身的列表。为什么奇怪?ISomething
的递归性质在我看来有点奇怪,但显然我不知道你是否真的需要递归来描述“某物”的层次结构。实际上,这是一个CSV文件的解析器,在将其写回文件时,必须将其作为一个整体读取,以保持父项/子项相关结构。ISomething实现的类包含一个执行X Y的构造函数。实例化后,方法Collection()会给出其自身的列表。为什么奇怪?ISomething
的递归性质在我看来有点奇怪,但显然我不知道你是否真的需要递归来描述“某物”的层次结构。实际上,这是一个CSV文件的解析器,在将其写回文件时,必须将其作为整体读取,以保持父/子项相关结构。