First
function in System.Linq.Enumerable
在System.Linq.Enumerable
中,以下是First
功能的实现方式:
public static TSource First<TSource>(this IEnumerable<TSource> source)
{
TSource? first = source.TryGetFirst(out bool found);
if (!found)
{
ThrowHelper.ThrowNoElementsException();
}
return first!;
}
TryGetFirst
被呼叫了,我们来看看:
private static TSource? TryGetFirst<TSource>(this IEnumerable<TSource> source, out bool found)
{
if (source is null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
}
return
#if !OPTIMIZE_FOR_SIZE
source is Iterator<TSource> iterator ? iterator.TryGetFirst(out found) :
#endif
TryGetFirstNonIterator(source, out found);
}
然后叫了TryGetFirstNonIterator
,我们来看看:
private static TSource? TryGetFirstNonIterator<TSource>(IEnumerable<TSource> source, out bool found)
{
if (source is IList<TSource> list)
{
if (list.Count > 0)
{
found = true;
return list[0];
}
}
else
{
using (IEnumerator<TSource> e = source.GetEnumerator())
{
if (e.MoveNext())
{
found = true;
return e.Current;
}
}
}
found = false;
return default;
}
正如我们所看到的,如果资源是IList<TSource>
,它确实会返回列表[0].
Source Code
Suggestion to SomeMethod
无论First
如何实施.你问的问题:
我知道如果GetMembers()返回IQUeryable,这可能会特别糟糕,但由于它只是一个列表,那么这样调用First()两次仍然不好吗?最佳做法是调用First()一次并将结果存储在变量中吗?
我认为超载就是您所需要的.
public async Task SomeMethod(Member member)
{
await DoSomething(member);
await DoSomethingElse(member);
}
public async Task SomeMethod(IEnumerable<Member> members)
{
await SomeMethod(members.First());
}