Foreach和可数

时间:2015-12-22 22:57:37

标签: c# .net foreach

为什么我们可以迭代项目

mList.ForEach((item) 
{
    item.xyz ....
}

对于一个简单的数组,我们需要强制foreach循环?

foreach(int i in arr)
    i.xyz

或使用委托类型?

Action<int> action = new Action<int>(myfunc);
Array.ForEach(intArray, action);

有什么不同?

2 个答案:

答案 0 :(得分:4)

第一种语法不正确。它应该是这样的:

mList.ForEach(item => 
{
    // item.xyz
});

ForEach是一种List<T>方法,可让您对列表中的每个项目调用Action<T>

另一方面foreach

  

语句为每个元素重复一组嵌入式语句   实现的数组或对象集合   System.Collections.IEnumerable或   System.Collections.Generic.IEnumerable接口。

话虽如此,ForEach只能在列表上调用,foreach可以在任何实现IEnumerable或IEnumerable的对象上调用。这是最重要的区别。

关于委托类型,没有任何区别。实际上,lambda表达式item=>{ item.xyz = ...}是代表的简写。

答案 1 :(得分:2)

该语言将foreach定义为IEnumerable的操作。因此,实现IEnumerable的所有内容都是可迭代的。但是,并非所有IEnumerable都是有意义的&#39;使用ForEach块时。

以此为例:

public static IEnumerable<MyObject> GetObjects()
{
    var i = 0;
    while(i < 30)
        yield return new MyObject { Name = "Object " + i++ };
}

然后你做这样的事情:

var objects = GetObjects();
objects.ForEach(o => o.Name = "Rob");
foreach (var obj in objects)
    Console.WriteLine(obj.Name);
编译的

IF 会打印Object 0Object 29 - 非Rob 30次。

这样做的原因是迭代器每次重置 重复可枚举。它对列表中的ForEach有意义,因为枚举已实现,并且每次迭代时都不会重新创建对象。

为了让ForEach能够使用可枚举项,您还需要实现该集合(例如将其放入列表中),但即使 也是如此并不总是可能,因为你可以有一个没有定义结束的枚举:

public static IEnumerable<MyObject> GetObjects()
{
    while(true)
        yield return new MyObject { Name = "Object " };
}

ForEachArray是有意义的 - 但由于我不知道的原因,它被定义为Array.ForEach(arr)而不是arr.ForEach() ForEach

故事的道德是,如果您认为需要List<T>块,您可能希望首先实现可枚举,通常是T[]或数组(function loadApps(){ AppManagerService.loadApps().then(function(apps){ $timeout(function() { // update your scope variables here. The refresh will occur automatically. $scope.apps = apps; console.log($scope.apps); }); }); } )。