对实际上是 List 的 IEnumerable<T> 多次调用 First() 是否不好?<T>

问题描述 投票:0回答:1
我找到了这个方法:

public async Task SomeMethod(IEnumerable<Member> members) { await DoSomething(members.First()); await DoSomethingElse(members.First()); }
它的名字是这样的:

List<Member> members = GetMembers(); await SomeMethod(members);
我知道如果

GetMembers()

返回一个
IQueryable<Member>
,这可能会特别糟糕,但由于它只是一个
List<Member>
,所以像这样调用
First()
两次仍然不好吗?
最好的做法是调用 
First()
 一次并将结果存储在变量中吗?

c# ienumerable .net-7.0 iqueryable
1个回答
0
投票

First
 功能于 
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>

,它确实返回 list[0]。
源代码

建议

SomeMethod

无论

First

如何实施。您问的问题:

我知道如果 GetMembers() 返回一个 IQueryable,这可能会特别糟糕,但由于它只是一个 List,所以像这样调用 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()); }
    
© www.soinside.com 2019 - 2024. All rights reserved.