나는 FirstOrDefault와 관련하여 어느 것이 "모범 사례"로 간주되는지 약간 궁금합니다.FirstOrDefault()는 LINQ 대 FirstArDefault()를 Lambda와 함께 사용합니까?
나는 이미이 질문을 보았습니다.이 질문은 제가 가지고있는 질문과 비슷하지만 제 질문에 대한 답변에 충분히 가깝지 않습니다.
"더 나은 코드"중 어느 것입니까? 그리고 왜? IMO, 그것은 청소기 코드를 만들면서
var foos = GetMyEnumerableFoos();
var foo1 = (from f in foos
where f.Bar == "spider monkey"
select f).FirstOrDefault();
/* OR */
var foo2 = foos.FirstOrDefault(f => f.Bar == "spider monkey");
나는 후자쪽으로 경향이있다. 그러나 나는 그곳에서 벌어지는 일의 기술적 인 "용기"가 다른면에서보다 효율적인지 아닌지에 대해 궁금합니다. 다른 유형의 IEnumerables를 사용하는 경우이 변경됩니까? 같은 DataTables 또는 문자열 배열 또는 LINQ 개체?
========= 존 소총의 게시물 올바른 가정
, 내가 리플렉터에보고 갔다 편집 ==========는 어디서 FirstOrDefault 모양을 참조하고 (=> f.Bar f를 == "거미 원숭이") foos.Where의 경우
FirstOrDefault()
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
if (source is Iterator<TSource>)
{
return ((Iterator<TSource>) source).Where(predicate);
}
if (source is TSource[])
{
return new WhereArrayIterator<TSource>((TSource[]) source, predicate);
}
if (source is List<TSource>)
{
return new WhereListIterator<TSource>((List<TSource>) source, predicate);
}
return new WhereEnumerableIterator<TSource>(source, predicate);
}
되는 공급 것이다 : 여기에 내가 생각 해낸거야. :
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
if (list.Count > 0)
{
return list[0];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
return enumerator.Current;
}
}
}
return default(TSource);
}
foos.FirstOrDefault (f => f.Bar == "spider monkey")의 경우;
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource local in source)
{
if (predicate(local))
{
return local;
}
}
return default(TSource);
}
것을 보면 아직도 나 효율성 특정 개체 유형에 대한 적절한 반복자를 사용하여이 추가됩니다 조금 혼란 잎? 아니면 모든 것을 건너 뛰고 루핑을 시작하고 테스트하는 것이 더 효율적입니까? 내 직감은 나에게 그것이 후자라고 다시 말합니다.
재미 있습니다. 나는 당신이 언급 한 그 세 가지 방법으로 어떤 일이 벌어지고 있는지를보기 위해 당신이 게시물 인 후에 조금 더 파고 들었다. 나는 나의 발견을 위에 게시했다. .. 그것은 확실히 나의 질문에 답하는 것을 돕는다. –
체크하지 않았지만'Where'' return's 결과가'IList'에 없다고 가정하기 때문에 두 개의 최종 루프는 사실상 동일합니다 :'MoveNext'는'Where ', FirstOrDefault (predicate) 호출이이를 명시 적으로 호출 할 때. 그러므로'Where' 버전은'false' (그리고'true'가 존재한다면)'술어'당 하나의 추가 호출을합니다. –