System.Linq.Enumerable.DefaultIfEmpty
の実装を追跡することで、このメソッドが使用されました。これは、次の趣のある詳細を除いて大丈夫になりますDefaultIfEmptyがこのように実装されているのはなぜですか?
// System.Linq.Enumerable
[IteratorStateMachine(typeof(Enumerable.<DefaultIfEmptyIterator>d__90<>))]
private static IEnumerable<TSource> DefaultIfEmptyIterator<TSource>(IEnumerable<TSource> source, TSource defaultValue)
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
do
{
yield return enumerator.Current;
}
while (enumerator.MoveNext());
}
else
{
yield return defaultValue;
}
}
IEnumerator<TSource> enumerator = null;
yield break;
yield break;
}
1)なぜコードは、配列が空でないことが確立された後、シーケンス全体を反復処理する必要があるのでしょうか?
2)なぜ収穫が最後に2回壊れますか?
3)enumerator
の最後にnullを明示的に設定する理由は何ですか?
私はこれでそれを残しているだろう:あなたが列挙を開始し、このコードは、列挙の別のレベルとして使用されているときに、全部を列挙しなければならないので
// System.Linq.Enumerable
[IteratorStateMachine(typeof(Enumerable.<DefaultIfEmptyIterator>d__90<>))]
private static IEnumerable<TSource> DefaultIfEmptyIterator<TSource>(IEnumerable<TSource> source, TSource defaultValue)
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
do
{
yield return enumerator.Current;
}
// while (enumerator.MoveNext());
}
else
{
yield return defaultValue;
}
}
// IEnumerator<TSource> enumerator = null;
yield break;
// yield break;
}
は[このソース(http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,1ff6169a97a478bf,references)違って見えます。デコンパイラを信頼しないで、元のソースコードを見てください。 –
ありがとうございます。 3つの質問のうちの最初の質問だけが残ります。 –
最初の質問は簡単です: 'DefaultIfEmpty'には一つの目的があります:シーケンス全体を返すか、空の場合はデフォルト値を返します。 'strings.Where(somecondition).DefaultIfEmpty(" foo ")。First()'と書かれたシーケンスは完全には列挙されませんが、最初の要素が生成されるまでのみ列挙されます。 –