C#Linq对Distinct()方法的结果执行方法

C# Linq execute method over results from Distinct() method

本问题已经有最佳答案,请猛点这里访问。

我有这样的代码,它将在distinct()返回的每个对象上执行console.writeline(x)。

1
objects.Distinct().ToList().ForEach(x => Console.WriteLine(x));

但是,如果不使用tolist(),如何实现相同的目标?


使用foreach

1
2
foreach(var x in objects.Distinct())
     Console.WriteLine(x);

你不需要清单,也不需要List.ForEach方法。只需使用一个简单的循环。

值得一提的是,任何序列都可以使用foreach扩展方法。

使用此扩展方法,可以使用以下代码:

1
objects.Distinct().ForEach(Console.WriteLine);


你没有。

.Distinct() is a method that operates on an IEnumerable, and
returns an IEnumerable (lazily evaluated). An IEnumerable is a
sequence: it is not a List. Hence, if you want to end up with a
list, put the .ToList() at the end.

这里有一个很好的解释


您可以通过创建自定义的foreach扩展来实现这一点。

测试程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void Main(string[] args)
{
    var objects = new List<DateTime>();

    objects.Add(DateTime.Now.AddDays(1));
    objects.Add(DateTime.Now.AddDays(1));
    objects.Add(DateTime.Now.AddDays(2));
    objects.Add(DateTime.Now.AddDays(2));
    objects.Add(DateTime.Now.AddDays(3));
    objects.Add(DateTime.Now.AddDays(3));
    objects.Add(DateTime.Now.AddDays(4));
    objects.Add(DateTime.Now.AddDays(4));
    objects.Add(DateTime.Now.AddDays(5));
    objects.Add(DateTime.Now.AddDays(5));

    objects.Distinct().ForEach(x => Console.WriteLine(x.ToShortDateString()));
}

扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static class Extensions
{
    public static void ForEach<ST>(this IEnumerable<ST> source, Action<ST> action)
    {
        IEnumerator<ST> enumerator = source.GetEnumerator();
        while (enumerator.MoveNext())
            action(enumerator.Current);
        enumerator.Dispose();
    }

    // OR

    public static void ForEach<ST>(this IEnumerable<ST> source, Action<ST> action)
    {
        foreach (var item in source)
            action(item);
    }
}

聚苯乙烯

请记住,如果您使用的是LINQ-2-SQL,这将不起作用,因为Linq2SQL查询只在某些特定操作(如ToListAsEnumerableFirstOrDefault以及其他一些操作)之后进行评估。


即使是丑陋的,物化也会有效果(把.ToList()放在最后):

1
2
3
4
5
6
7
objects
  .Distinct()
  .Select(x => {
     Console.WriteLine(x);
     return 1; // <- Select must return something
    })
  .ToList(); // <- this will force Linq to perform Select

一个更好的方法就是列举:

1
2
foreach (var x in objects.Distinct())
  Console.WriteLine(x);