Distinct()が返すオブジェクトのすべてでConsole.WriteLine(x)を実行するこのコードがあります。C#LinqはDistinct()メソッドの結果よりメソッドを実行します
ただし、ToList()を使用せずに同じことを達成するにはどうすればよいですか? foreach
を使用することにより
Distinct()が返すオブジェクトのすべてでConsole.WriteLine(x)を実行するこのコードがあります。C#LinqはDistinct()メソッドの結果よりメソッドを実行します
ただし、ToList()を使用せずに同じことを達成するにはどうすればよいですか? foreach
を使用することにより
:
foreach(var x in objects.Distinct())
Console.WriteLine(x);
あなたがリストを必要としない、あなたはList.ForEach
方法を必要としません。単純なループを使用してください。
どのような価値があるのかについては、どのような種類の配列でもForEach
extension methodです。あなたはこのコードを使用することができ、この拡張メソッドで
:
objects.Distinct().ForEach(Console.WriteLine);
あなたにはありません。
.Distinct()はIEnumerableで動作するメソッドであり、 はIEnumerable(遅延評価された)を返します。 IEnumerableは シーケンスです。リストではありません。したがって、最後に リストにしたい場合は、最後に.ToList()を入れてください。
でも醜いていることhere
のための素晴らしい説明があり、マテリアは(最後で.ToList()
を入れて)行います:
objects
.Distinct()
.Select(x => {
Console.WriteLine(x);
return 1; // <- Select must return something
})
.ToList(); // <- this will force Linq to perform Select
より良いアプローチはちょうどです列挙:
foreach (var x in objects.Distinct())
Console.WriteLine(x);
最初のコードサンプルでは、Console.WriteLineが何も返さないため、おそらく例外があります。メソッド 'System.Linq.Enumerable.Select
@Chris Dunaway:私は本当に何かを返さなければならないのを見ました。私の編集を参照してください –
カスタムForEach
拡張を作成することでこれを達成できます。
テストプログラム
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()));
}
拡張
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
あなたはLINQ-2-SQLを使用している場合は、これがないということを覚えておいてくださいlinq2sqlクエリはspの後にのみ評価されるためToList
,AsEnumerable
またはFirstOrDefault
(およびその他のもの)のようなエコな行動。
なぜ、foreachを使うのではなく、あなたのソースを明示的に列挙していますか? – Chris
ほとんどの習慣... 2年前に私はforeachのパフォーマンスについて何かを読んできました。私が機会を得たときには、列挙子を使ってコードを書いています(そのコードはあまり見られません)。 –
しかし、列挙子が使い捨てであれば自動的に破棄されるので、foreachが優れています。 –
これはなぜ機能しませんか? objects.Distinct()。Select(x => Console.WriteLine(x)) – Zwierzak
@Zwierzak:2つの理由があります。最初は、あなたが本当にあなたの選択から返される何かを必要とすることです。コンパイラは、選択ラムダが戻ってきた型を調べることができないので、コンパイラはそれに不満を持ちます。あなたは '.Select(x => {Console。WriteLine(x); return x;}) 'しかし、遅延評価に問題があります。あなたが作成している 'IEnumerable'を列挙するまで、実際には' Console.WriteLine'を実行しません。これは、ToList()を呼び出すこと、または 'ToList()'を使うことを意味します... – Chris
つまり、簡単にしようとすると、.Distinc()を呼び出すと、その時点でアクションは実行されません。 ).ToList()を呼び出すと、値が評価されます。 – Brduca