Select
接口,则 LINQ的方法Where
,SelectMany
,IList<T>
(也许不确定,其他方法)使用优化的实现-它不使用{{1 }}方法,但改为通过索引检索元素(我想至少是在dotnet核心中,以避免使用枚举器开销)。
是否可以针对某些类型禁用该优化?
我有GetEnumerator
实现,该实现代理对另一个集合的所有调用,因此,使用枚举器迭代所有元素实际上比按索引获取所有元素快得多。
答案 0 :(得分:0)
以下是Linq方法,它们查看集合实际上是IList
还是ICollection
并使用索引访问而不是枚举器:
First
/ FirstOrDefault
/ Single
/ SingleOrDefault
(如果未传递谓词,则使用list[0]
)Last
/ LastOrDefault
(如果未传递谓词,则使用list[count-1]
)ElementAt
/ ElementAtOrDefault
Count
(如果不使用谓词,则调用ICollection.Count()
)Contains
(呼叫ICollection.Contains
) Select
,Where
,OrderBy
,所有其他人都将使用枚举器。
一些选项是:
Select(x => x)
,从而用枚举器包装集合答案 1 :(得分:0)
当然可以。专门为您的类型实现给定的方法。您可以提供特定于类型的实现,既可以作为扩展方法也可以作为实例方法,编译器会选择它们,因为它们更加具体(自然地,扩展方法必须在范围内才能被考虑)。
可以找到针对System.Collections.Immutable.ImmutableArray<T>
的类型特定的LINQ方法优化的示例。
答案 2 :(得分:0)
我的建议是创建一个IEnumerable扩展函数,该函数接受一个输入序列,并返回与IEnumerable相同的序列。
请参见Extension Methods Demystified
public static IEnumerable<TSource> ToEnumerable (this IEnumerable<TSource> source)
{
foreach (var sourceItem in source)
yield return sourceItem
}
用法:
List<Person> persons = ...
var personList = persons.ToList(); // uses the fact that Persons implements IList
var otherList = persons.ToEnumerable().ToList();
// does not implement IList<...>, and thus doesn't use the optimization