我正在尝试使用OrderedDictionary作为下面扩展函数的参数(顺便说一句,如果你认为collection.Reverse().Where(i => predicate(i)).Take(n)
会更好,请告诉我!),但是我使用的通用OrderedDictionary实现(基于this version)没有实现IList。
集合只需要使用基于整数的索引(OrderedDictionary这样做)提供对其元素的访问。
是否有其他方法可以指定此要求,而不会产生过载?
/// <summary>
/// Return n elements, starting from the end of collection, that satisfy predicate.
/// </summary>
/// <param name="collection"></param>
/// <param name="predicate"></param>
/// <param name="n">Max number of elements to return</param>
/// <returns></returns>
public static IEnumerable<T> LastBefore<T>(this IList<T> collection, Func<T, bool> predicate, int n) {
if (collection == null)
{
throw new ArgumentNullException("collection");
}
for (int i = collection.Count - 1; i >= 0; i--)
{
if (n == 0) break;
if (predicate(collection[i]))
{
--n;
yield return collection[i];
}
}
}
答案 0 :(得分:1)
根据the MSDN about type constraints,遗憾的是没有。
最好你可以创建an interface that requires an indexer,但显然你不能用内置类做到这一点(除非你为此目的定义了一个包装类)。
答案 1 :(得分:1)
我建议定义一个IReadableList接口;如果不是读写索引器不算作只读索引器的实现这样的事实,这样的东西可能是IList的父(恕我直言,它应该是无论如何)。现有的IList实现将不实现IReadableList,除非包装,唉,但是具有只读列表接口将使协方差的概念更加有用,因为IReadableList&lt; Cat&gt;可以用作IReadableList&lt; Animal&gt;。
顺便说一下,我倾向于认为IList&lt; T&gt;不会从非泛型IList继承,也许它应该。任何IList&lt; T&gt;如果非泛型实现是只读的,则可以以类型安全的方式实现IList。即使从未真正从非泛型IList中读取任何对象,实现它也会允许一个想要IEnumerable&lt; Animal&gt;的例程。但是给出了IList&lt; Cat&gt; [当然,它实现了IEnumerable&lt; Cat&gt;,因此隐式地IEnumerable&lt; Animal&gt;]来获取集合的Count而不必枚举它。
答案 2 :(得分:0)
您可以在任何IEnumerable<T>
上使用ElementAt。对于实现IList<T>
的集合,这将使用快速索引而不是枚举所请求的索引之前的所有元素。这提供了只读访问权限,也适用于没有内置索引支持的集合,尽管性能下降。您通常会记录该方法,以指示支持索引的集合更适合作为传入的参数。
如果您需要提供读写访问权限,IList<T>
可能是一个合理的约束条件;如果你需要仅限于索引器的东西,最好的办法是创建一个封装了提供的IList<T>
的浅包装类,但只给消费者一个索引器。