Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 填充哈希集<;T>;使用所有的ISomething实现_C#_.net - Fatal编程技术网

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文件的解析器,在将其写回文件时,必须将其作为整体读取,以保持父/子项相关结构。