是否有一个接口指定参数(集合)可以用整数索引?

时间:2011-10-27 13:20:27

标签: c# .net list data-structures interface

我正在尝试使用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];
        }
    }
}

3 个答案:

答案 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>的浅包装类,但只给消费者一个索引器。