List<T>.ForEach(Action<T> action) 方法实际上是如何工作的?

How does the List<T>.ForEach(Action<T> action) method actually work?

我查看了 List.ForEach(Action action) 方法的文档,但它只说明了它的作用,没有说明它是如何做的。我知道它需要一个动作并对列表的所有元素执行该动作。但是它用来完成这个的实际代码是什么?有没有一种方法可以使我自己的 ForEach 方法与列表 ForEach 方法的工作方式相同?

我过去曾想压缩我的 ForEach 循环,这看起来在某些情况下效果很好,尤其是当我使用自定义 类.

我将从 c# 源代码中提取 if,它是 published online on a dedicated site at MS and also on GitHub - 可收藏的有用资源:

 public void ForEach(Action<T> action) {
        if( action == null) {
            ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
        }
        Contract.EndContractBlock();

        int version = _version;

        for(int i = 0 ; i < _size; i++) {
            if (version != _version && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) {
                break;
            }
            action(_items[i]);
        }

        if (version != _version && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
    }

大多数情况下,它只是用于版本检查和抛出的绒毛,核心部分是一个 for 循环,它采用您提供的方法并调用它依次传入每个列表项:

    public void ForEach(Action<T> action) {

        for(int i = 0 ; i < _size; i++) {
            action(_items[i]);
        }

    }

你完全可以自己写类,看起来就像那样。这是 .NET 框架版本 - 核心版本不会有太大差异

请注意,这并不是一个巨大的字符节省:

foreach(var v in vList) myMethod(v);
vList.ForEach(myMethod);

foreach(var v in vList)
  if(v.X > 10)
    Console.WriteLine(v.Y);

vList.ForEach(v => {
  if(v.X > 10)
    Console.WriteLine(v.Y);
});

对于大多数人来说,随着 foreach 变长,它仍然具有相当的可读性,而当您开始使用多行 lambda 时,它们最终可能会看起来更乱一些,而且不会明显更简洁