Lor*_*oro 6 c# linq extension-methods readonly-collection
我正在处理IReadOnlyCollection一些对象.
现在我有点惊讶,因为我可以使用linq扩展方法ElementAt().但我无法访问IndexOf().
这对我来说看起来有点不合逻辑:我可以在给定位置获取元素,但我无法获得该元素的位置.
它有具体原因吗?
我已经读过 - > 如何获取IEnumerable中元素的索引?我对这个回应并不满意.
Mik*_*kis 33
IReadOnlyList<T>没有IndexOf() 任何好的理由。如果真要找个理由提起,那是历史原因:
早在 90 年代中期 C# 诞生时,人们还没有完全意识到不变性和只读的好处,因此IList<T>不幸的是,他们融入语言的界面是可变的。
正确的做法是提出IReadOnlyList<T>作为基本接口,并IList<T>扩展它,仅添加突变方法,但事实并非如此。
IReadOnlyList<T>在相当长的一段时间后才发明IList<T>,到那时重新定义IList<T>和扩展为时已晚IReadOnlyList<T>。所以,IReadOnlyList<T>是从头开始构建的。
他们不能 make IReadOnlyList<T>extend IList<T>,因为那样它会继承变异方法,所以他们基于IReadOnlyCollection<T>andIEnumerable<T>取而代之。他们添加了this[i]索引器,但随后他们要么忘记添加其他方法,如IndexOf(),要么故意省略它们,因为它们可以作为扩展方法实现,从而使接口更简单。但是他们没有提供任何这样的扩展方法。
所以,这里是一个扩展方法,添加IndexOf()到IReadOnlyList<T>:
using Collections = System.Collections.Generic;
public static int IndexOf<T>( this Collections.IReadOnlyList<T> self, T elementToFind )
{
int i = 0;
foreach( T element in self )
{
if( Equals( element, elementToFind ) )
return i;
i++;
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)
请注意,此扩展方法不如接口中内置的方法强大。例如,如果您正在实现一个集合,它需要一个IEqualityComparer<T>作为构造(或其他独立)参数的集合,这个扩展方法将完全不知道它,这当然会导致错误。(感谢 Grx70 在评论中指出这一点。)
| 归档时间: |
|
| 查看次数: |
2315 次 |
| 最近记录: |