Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.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#foreach_C#_Linq_Generics_Generic Collections - Fatal编程技术网

接口集合上的C#foreach

接口集合上的C#foreach,c#,linq,generics,generic-collections,C#,Linq,Generics,Generic Collections,我想知道C#/LINQ是否内置了任何功能来简化以下内容: foreach(var item in collection) { if (item.GetType() == typeof(Type1) DoType1(item as Type1); else if (item.GetType() == typeof(Type2)) DoType2(item as Type2); ... } 指的是: collection.ForEachT

我想知道C#/LINQ是否内置了任何功能来简化以下内容:

foreach(var item in collection)
{
    if (item.GetType() == typeof(Type1)
         DoType1(item as Type1);
    else if (item.GetType() == typeof(Type2))
         DoType2(item as Type2);
    ...
}
指的是:

collection.ForEachType(Type1 item => DoType1(item), Type2 item => DoType2(item));
我意识到以下几点很接近:

collection.OfType<Type1>.ToList().Foreach(item => DoType1(item));
collection.OfType<Type2>.ToList().Foreach(item => DoType2(item));
collection.OfType.ToList().Foreach(item=>DoType1(item));
Foreach(item=>DoType2(item));

但是,当代码依赖于集合的顺序时,它就不起作用了。

LINQ中没有内置任何内容,不。我要提醒您不要像这样使用
GetType()
,通常更适合使用
is
as
然后进行空检查:

foreach(var item in collection)
{
    Type1 itemType1 = item as Type1;
    if (itemType1 != null)
    {
         DoType1(itemType1);
         continue;
    }
    Type2 itemType2 = item as Type1;
    if (itemType2 != null)
    {
         DoType2(itemType1);
         continue;
    }
    // etc
}
这样,派生类的处理方式通常是合适的


请注意,这种类型的测试通常是不受欢迎的-通常最好将行为作为虚拟方法放入类型本身,并以多态方式调用它。

LINQ中没有内置任何内容,不。我要提醒您不要使用
GetType()
像这样-通常更适合使用
is
as
然后进行空检查:

foreach(var item in collection)
{
    Type1 itemType1 = item as Type1;
    if (itemType1 != null)
    {
         DoType1(itemType1);
         continue;
    }
    Type2 itemType2 = item as Type1;
    if (itemType2 != null)
    {
         DoType2(itemType1);
         continue;
    }
    // etc
}
这样,派生类的处理方式通常是合适的

请注意,这种类型的测试通常是不受欢迎的-通常最好将行为作为虚拟方法放入类型本身,并以多态方式调用它。

不是默认情况。试试看

反应式扩展和提升都包含ForEach实现。两者都有许多扩展linq功能的方法

您将找不到ForEachType,但ForEach(Rx或Elevate)和OfType(Linq)将为您提供所需的内容。

默认情况下不是这样。试试看

反应式扩展和提升都包含ForEach实现。两者都有许多扩展linq功能的方法


你找不到ForEachType,但是ForEach(Rx或Elevate)和OfType(Linq)会给你你想要的。

在我看来,如果你只是用“item is Type1”替换“item.GetType()==typeof(Type1)”,你的ForEach循环就会足够简单。

如果你只是用“item.GetType()==typeof(Type1)”替换“item.GetType()==typeof(Type1)”“item是Type1”,您的foreach循环将足够简单。

我要看的第一件事是多态性;我可以改为使用虚拟方法和
item.DoSomething()

接下来我要看的是枚举鉴别器,即

switch(item.ItemType) {
    case ItemType.Foo: ...
    case ItemType.Bar: ...
}
(并将鉴别器添加到公共接口/基类)

如果类型可以是任何类型,那么4.0有一个诀窍;如果您为每个重载调用相同的te方法,您可能会让
dynamic
担心如何选择它:

dynamic x = item;
DoSomething(x);

我要看的第一件事是多态性;我可以改为使用虚拟方法和
item.DoSomething()

接下来我要看的是枚举鉴别器,即

switch(item.ItemType) {
    case ItemType.Foo: ...
    case ItemType.Bar: ...
}
(并将鉴别器添加到公共接口/基类)

如果类型可以是任何类型,那么4.0有一个诀窍;如果您为每个重载调用相同的te方法,您可能会让
dynamic
担心如何选择它:

dynamic x = item;
DoSomething(x);

比如说:

var typeActions = new Dictionary<Type,Action<Object>>();
typeActions.Add(typeof(Type1), obj => DoType1((Type1)obj));
typeActions.Add(typeof(Type2), obj => DoType2((Type2)obj));

collection.Foreach(obj => typeActions[obj.GetType()](obj));
var-typeActions=newdictionary();
添加(typeof(Type1),obj=>DoType1((Type1)obj));
添加(typeof(Type2),obj=>DoType2((Type2)obj));
Foreach(obj=>typeActions[obj.GetType()](obj));

此代码未经测试(直接在浏览器中键入)。

以下内容如何:

var typeActions = new Dictionary<Type,Action<Object>>();
typeActions.Add(typeof(Type1), obj => DoType1((Type1)obj));
typeActions.Add(typeof(Type2), obj => DoType2((Type2)obj));

collection.Foreach(obj => typeActions[obj.GetType()](obj));
var-typeActions=newdictionary();
添加(typeof(Type1),obj=>DoType1((Type1)obj));
添加(typeof(Type2),obj=>DoType2((Type2)obj));
Foreach(obj=>typeActions[obj.GetType()](obj));
此代码未经测试(直接在浏览器中键入)。

您的里程可能会有所不同

Dictionary<Type, Action<object>> typeMap = new Dictionary<Type, Action<object>>();
typeMap[typeof(Type1)] = item => DoType1(item as Type1);
typeMap[typeof(Type2)] = item => DoType2(item as Type2);

var typeToActionQuery =
  from item in source
  let type = item.GetType()
  where typeMap.ContainsKey(type)
  select new
  {
    input = item;
    method = typeMap[type]
  };

foreach(var x in typeToActionQuery)
{
  x.method(x.input);
}
您的里程可能会有所不同

Dictionary<Type, Action<object>> typeMap = new Dictionary<Type, Action<object>>();
typeMap[typeof(Type1)] = item => DoType1(item as Type1);
typeMap[typeof(Type2)] = item => DoType2(item as Type2);

var typeToActionQuery =
  from item in source
  let type = item.GetType()
  where typeMap.ContainsKey(type)
  select new
  {
    input = item;
    method = typeMap[type]
  };

foreach(var x in typeToActionQuery)
{
  x.method(x.input);
}

当您说代码依赖于顺序时,是否意味着您在编译时知道,例如,项1始终是字符串,项2始终是双精度的?@DJ Quimby+1。没有注意到。奇怪。听起来像DoType1和DoType2,应该抽象为“Do”“类型1和类型2上的方法。“这样你就可以做一个foreach,然后在每个foreach上都打电话给do。”RitchMelton同意。如果已经知道了顺序,那么foreach循环可能是不必要的。为什么要使用反射来检查确切的类型,然后向右转,使用“as”操作符进行运行时类型检查?如果说“if(item是T1)DoT1(item是T1)”,或者“T1 T1=item是T1;if(T1!=null)DoT1(T1);”,不是会更清楚吗?当你说代码依赖于顺序时,是不是说你在编译时知道例如item 1总是一个字符串,item 2总是一个双精度?@DJ Quimby+1。错过了。奇怪。类似于DoType1和DoType2的声音应该被抽象为type1和type2上的“Do”方法。“这样你就可以做一个foreach,然后在每个foreach上都打电话给do。”RitchMelton同意。如果已经知道了顺序,那么foreach循环可能是不必要的。为什么要使用反射来检查确切的类型,然后向右转,使用“as”操作符进行运行时类型检查?如果说“if(item是T1)DoT1(item是T1)”,或者“T1 T1=item是T1;if(T1!=null)DoT1(T1);”不是更清楚吗?这可能是个坏主意。不考虑派生类型。这可能是个坏主意。不考虑派生类型。最好指出这些类型的哪些功能可能适用于这里。通常的类型是LINQ。最好能指出它们的哪些特性可能适用于这里。类型为LINQ。