特定のケースでは、とを呼び出すFirst
とWhere
、string[]
呼び出されるメソッドはEnumerable.Where
とEnumerable.First
拡張メソッドです。
Enumerable.Where
これを行います:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
// null checks omitted
if (source is TSource[])
return new WhereArrayIterator<TSource>((TSource[])source, predicate);
//the rest of the method will not execute
}
のコンストラクタは次のことをWhereArrayIterator
行います。
public WhereArrayIterator(TSource[] source, Func<TSource, bool> predicate) {
this.source = source;
this.predicate = predicate;
}
したがって、イテレータを作成することを除いて、ここでは実際には何も行われません。
First
述語のない最初の方法はこれを行います:
public static TSource First<TSource>(this IEnumerable<TSource> source) {
//null check
IList<TSource> list = source as IList<TSource>;
if (list != null) {
//this branch is not taken as string[] does not implement IList<string>
if (list.Count > 0) return list[0];
}
else {
//this is actually the WhereArrayIterator from before
using (IEnumerator<TSource> e = source.GetEnumerator()) {
if (e.MoveNext())
return e.Current;
}
}
throw Error.NoElements();
}
しかし、2番目First
はこれを行います
public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
//null checks
foreach (TSource element in source) {
if (predicate(element)) return element;
}
throw Error.NoMatch();
}
アレイの場合、これは直接線形アクセスと同じくらい高速です。
一言で言えば、これはFirst(predicate)
、配列の呼び出しが、大きくはないが、それでも検出可能な要因によって、いくらか高速になることを意味します。これはリストには当てはまらないかもしれませんしIQueryable
、まったく別の話であるオブジェクトにも当てはまらないでしょう。
ただし、これは最悪の場合、マイクロ最適化です。これが何百万回も行われない限り、それはあまり多くの秒を節約しません。私は今これを知っていますが、私はまだ読んで理解するためにより明確なものを使用します。