我尝试在 MSDN、SO 和 Web 上搜索,但找不到答案。
假设我有一个收藏品FirstOrDefault()
。假设它找到了该项目。它是停止并返回项目还是继续搜索并妨碍性能?
我尝试在 MSDN、SO 和 Web 上搜索,但找不到答案。
假设我有一个收藏品FirstOrDefault()
。假设它找到了该项目。它是停止并返回项目还是继续搜索并妨碍性能?
如果您对此仍然含糊不清,.NET 框架中的源代码是从这里实现的:
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> e = source.GetEnumerator()) {
if (e.MoveNext()) return e.Current;
}
}
return default(TSource);
}
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 element in source) {
if (predicate(element)) return element;
}
return default(TSource);
}
显然,如果成立,它将停止
FirstOrDefault
将迭代直到找到元素,并且只有在找不到元素时才需要迭代整个元素IEnumerable
。
它停止并返回。
这是相关的反编译代码(对于FirstOrDefault()
和FirstOrDefault(predicate)
)
[__DynamicallyInvokable]
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);
}
这里它所做的是检查它是否实现IList
,如果实现,则返回第一项,如果有的话。如果没有,它会获取一个枚举器并尝试执行MoveNext
. 如果成功,则返回Enumerator.Current
. 否则它只返回类型的默认值 ( TSource
)
[__DynamicallyInvokable]
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 source1 in source)
{
if (predicate(source1))
return source1;
}
return default (TSource);
}
在这里,它首先检查所有 args are not null
,然后 foreaches 直到找到与谓词匹配的项目,然后返回它。如果没有,那么它只返回该类型的默认值。
(如果您想知道如何获取源代码,我使用了 dotPeek。这是一个很棒的工具!)
我希望它确实如此..但这里有几种方法可以告诉你:
测试一下。做一个大集合(这需要很长时间才能搜索),然后将要查找的元素放在开头,然后放在结尾。这两个测试所用的时间应该不同,第一个应该更短。
查看.Net 源代码,然后自己看看。