C#语法 - Lambda表达式示例 - 对泛型列表进行ForEach()操作

50

首先,我知道框架中已经有一些通用的List<>类的方法来迭代List<>

但是,举个例子,写一个ForEach方法对List<>中的每个对象进行迭代,并在每个对象上执行Console.WriteLine(object.ToString()),正确的语法是什么?这个方法以List<>作为第一个参数,lambda表达式作为第二个参数。

大多数示例都是使用扩展方法或涉及LINQ。我正在寻找一个普通的方法示例。

7个回答

79
public void Each<T>(IEnumerable<T> items, Action<T> action)
{
    foreach (var item in items)
        action(item);
}

...并将其命名为:

Each(myList, i => Console.WriteLine(i));

很好。现在我看到的 Func<> 语法在哪里发挥作用? - BuddyJoe
14
Func<>委托用于具有返回值的方法,而Action<>委托用于没有返回值的方法。这是唯一的区别。 - TheSoftwareJedi
1
所以在您的情况下,您不需要从console.writeline返回任何东西,因此Action <T>就足够了。 - TheSoftwareJedi
另外,您可以直接使用方法组“Console.WriteLine”,而不是lambda表达式“i => Console.WriteLine(i)”。 - Massif

55

这是你想要的吗?

int[] numbers = { 1, 2, 3 };
numbers.ToList().ForEach(n => Console.WriteLine(n));

是的,这很方便,我已经使用过了。+1。当我提出问题的时候,我想我只是在尝试掌握基本的 C# lambda 语法,特别是与泛型一起使用时。 - BuddyJoe
5
好的,但我们必须考虑ToList()是一个O(n)操作。 - Toni Rossmann

42

以上代码也可以使用更少的代码来编写:

new List<SomeType>(items).ForEach(
    i => Console.WriteLine(i)
);

这将创建一个通用的列表,并使用IEnumerable填充它,然后调用列表对象的ForEach方法。


1
问题询问如何编写方法(而不是如何调用它),并指定他不想使用LINQ或扩展方法。 - StriplingWarrior
这很方便,但创建新列表的开销(至少意味着迭代项目一次以上)通常不值得。 - dumdum

15
public static void Each<T>(this IEnumerable<T> items, Action<T> action) {
foreach (var item in items) {
    action(item);
} }

...然后这样称呼它:

myList.Each(x => { x.Enabled = false; });

2
在Each中展示如何进行多个操作是一个加分项。 - Amir978

4

想要表达的是,如果有人提供一个扩展方法作为答案,其实不用太担心,因为扩展方法只是调用实例方法的一种很酷的方式。我知道你想要不使用扩展方法得到答案。无论这个方法是定义为静态的、实例的或扩展的——结果都是相同的。

下面的代码使用了被接受的答案中的代码来定义一个扩展方法和一个实例方法,并创建了一个单元测试来展示输出结果是相同的。

public static class Extensions
{
    public static void Each<T>(this IEnumerable<T> items, Action<T> action)
    {
        foreach (var item in items)
        {
            action(item);
        }
    }
}

[TestFixture]
public class ForEachTests
{
    public void Each<T>(IEnumerable<T> items, Action<T> action)
    {
        foreach (var item in items)
        {
            action(item);
        }
    }

    private string _extensionOutput;

    private void SaveExtensionOutput(string value)
    {
        _extensionOutput += value;
    }

    private string _instanceOutput;

    private void SaveInstanceOutput(string value)
    {
        _instanceOutput += value;
    }

    [Test]
    public void Test1()
    {
        string[] teams = new string[] {"cowboys", "falcons", "browns", "chargers", "rams", "seahawks", "lions", "heat", "blackhawks", "penguins", "pirates"};

        Each(teams, SaveInstanceOutput);

        teams.Each(SaveExtensionOutput);

        Assert.AreEqual(_extensionOutput, _instanceOutput);
    }
}

简单来说,将扩展方法转换为实例方法的唯一步骤是删除方法的 static 修饰符和第一个参数。

这个方法

public static void Each<T>(this IEnumerable<T> items, Action<T> action)
{
    foreach (var item in items)
    {
        action(item);
    }
 }

变成

public void Each<T>(Action<T> action)
{
    foreach (var item in items)
    {
        action(item);
    }
 }

0

标准:

foreach (Item i in allItems)
{
   i.FK_ItemStatus_CustomCodeID = itemStatuses.Where(
      x => x.CustomCodeID == i.ItemStatus_CustomCodeID).FirstOrDefault();                        
}

Lambda:

allItems.ForEach(
   i => i.FK_ItemStatus_CustomCodeID = 
      itemStatuses.Where(
         x => x.CustomCodeID == i.ItemStatus_CustomCodeID).FirstOrDefault()
      );

0

您可以遍历列表中的每个字符串,甚至可以使用单个语句在整个泛型中进行搜索,这使得搜索变得更加容易。

public static void main(string[] args)
{
List names = new List();

names.Add(“Saurabh”);
names.Add("Garima");
names.Add(“Vivek”);
names.Add(“Sandeep”);

string stringResult = names.Find( name => name.Equals(“Garima”));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接