I have this code that will execute Console.WriteLine(x) on every object in what Distinct() will return.
objects.Distinct().ToList().ForEach(x => Console.WriteLine(x));
However, how can I achieve the same thing without using ToList()?
I have this code that will execute Console.WriteLine(x) on every object in what Distinct() will return.
objects.Distinct().ToList().ForEach(x => Console.WriteLine(x));
However, how can I achieve the same thing without using ToList()?
By using foreach
:
foreach(var x in objects.Distinct())
Console.WriteLine(x);
You don't need the list and you don't need the List.ForEach
method. Just use a plain loop.
For what it's worth, a ForEach
extension method for any kind of sequence.
With this extension method you could use this code:
objects.Distinct().ForEach(Console.WriteLine);
You don't.
.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.
There is a nice explanation for that here
Even being ugly, materialization will do (put .ToList()
at the end):
objects
.Distinct()
.Select(x => {
Console.WriteLine(x);
return 1; // <- Select must return something
})
.ToList(); // <- this will force Linq to perform Select
A much better approach is just enumerate:
foreach (var x in objects.Distinct())
Console.WriteLine(x);
You could achieve this by creating your custom ForEach
extension.
Test Program
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()));
}
Extension
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);
}
}
PS
Keep in mind that if you are using LINQ-2-SQL, this won't work since linq2sql queries are only evaluated after some specific actions like ToList
, AsEnumerable
or FirstOrDefault
(and some others).