C# 对于IList是否有类似ForEach的方法?

C# 对于IList是否有类似ForEach的方法?,c#,linq,extension-methods,C#,Linq,Extension Methods,可能重复: List有一个名为ForEach的方法,它对每个元素执行传递的操作 var names = new List<String>{ "Bruce", "Alfred", "Tim", "Richard" }; names.ForEach(p => { Console.WriteLine(p); }); var name=新列表{“布鲁斯”、“阿尔弗雷德”、“蒂姆”、“理查德”}; names.ForEach(p=>{Console.WriteLine(p);})

可能重复:

List
有一个名为
ForEach
的方法,它对每个元素执行传递的操作

var names = new List<String>{ "Bruce", "Alfred", "Tim", "Richard" };

names.ForEach(p =>  { Console.WriteLine(p); });
var name=新列表{“布鲁斯”、“阿尔弗雷德”、“蒂姆”、“理查德”};
names.ForEach(p=>{Console.WriteLine(p);});
但是如果
名称
不是一个
列表
,而是一个
IList
,该怎么办
IList
没有类似于
ForEach
的方法

有别的选择吗

如果您的
IList
是一个数组(
T[]
),那么您可以使用类似于
列表上的
ForEach
的方法。您可以为自定义的
IList
IEnumerable
或您喜欢的任何内容创建扩展方法

public static void ForEach<T>(this IList<T> list, Action<T> action)
{
    foreach (T t in list)
        action(t);
}

如果是这样,您可以在
IEnumerable
上创建扩展方法。注意,终止调用
ForEach
执行
Linq
查询。如果您不想要它,也可以使用
yield
语句并返回
IEnumerable
返回:

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> list, Action<T> action)
{
    foreach (T t in list)
    {
        action(t);
        yield return t;
    }
}
正如我要说的,这些并没有什么不好的。这只是个人喜好对于嵌套的
foreach
s,或者如果它涉及到在
foreach
循环中执行的多行代码,我不会使用它,因为这显然是不可读的。
但是对于我发布的简单示例,我喜欢它。看起来干净简洁


编辑:查看性能链接顺便说一句:

将此代码添加到静态类并称之为扩展:

public static void ForEach<T>(this IList<T> list, Action<T> action) {
    foreach(var item in list) {
        action.Invoke(item);
    }
}
publicstaticvoidforeach(此IList列表,操作){
foreach(列表中的变量项){
行动.调用(项目);
}
}

使用
foreach
循环:

foreach (var p in names) {
    Console.WriteLine(p);
}

如果实际上不能提高可读性,就没有理由到处使用委托和扩展方法;与
foreach
方法相比,
foreach
循环更明确地告诉读者正在做什么。

您可以创建一个扩展方法,并使用
void List.foreach(Action-Action)
的大部分实现。您可以在该站点下载源代码

基本上你会以这样的方式结束:

public static void ForEach<T>(this IList<T> list, Action<T> action) 
{
    if (list == null) throw new ArgumentNullException("null");
    if (action == null) throw new ArgumentNullException("action");

    for (int i = 0; i < list.Count; i++)
    {
        action(list[i]);
    }
}
publicstaticvoidforeach(此IList列表,操作)
{
如果(list==null)抛出新的ArgumentNullException(“null”);
如果(action==null)抛出新的ArgumentNullException(“action”);
for(int i=0;i
它比使用
foreach
语句的其他实现稍好一些,因为它利用了IList包含索引器这一事实

虽然我不同意O.R.Mapper的答案,但有时在有许多开发人员的大型项目中,很难让每个人都相信
foreach
语句更清晰。更糟糕的是,如果您的API基于接口(IList)而不是具体类型(List),那么使用
List.ForEach方法的开发人员可能会开始在IList引用上调用
ToList
!我知道,因为它发生在我以前的项目中。我在我们的公共API中到处使用收集接口。我花了一段时间才注意到,许多不习惯这种方式的开发人员开始以惊人的速度调用
ToList
。最后,我将此扩展方法添加到每个人都在使用的公共程序集中,并确保从代码库中删除对
ToList
的所有不必要的调用

public static void ForEach<T>(this IList<T> list, Action<T> action) {
    foreach(var item in list) {
        action.Invoke(item);
    }
}
foreach (var p in names) {
    Console.WriteLine(p);
}
public static void ForEach<T>(this IList<T> list, Action<T> action) 
{
    if (list == null) throw new ArgumentNullException("null");
    if (action == null) throw new ArgumentNullException("action");

    for (int i = 0; i < list.Count; i++)
    {
        action(list[i]);
    }
}