协方差和IList的 [英] Covariance and IList

查看:279
本文介绍了协方差和IList的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一个协变集的项目可以通过索引进行检索。 IEnumerable的是唯一的.NET集合,我所知道的是协变,但它并没有这个指标的支持。

I would like a Covariant collection whose items can be retrieved by index. IEnumerable is the only .net collection that I'm aware of that is Covariant, but it does not have this index support.

具体而言,我想做到这一点:

Specifically, I'd like to do this:

List<Dog> dogs = new List<Dog>();

IEnumerable<Animal> animals = dogs;
IList<Animal> animalList = dogs; // This line does not compile

现在,我所知道的,为什么这是一个问题。列表实现ICollection的,有一个Add方法。达铸造动物的IList,这将使后续的code添加任何类型的动物是不是真正的List集合允许的。

Now, I'm aware of why this is a problem. List implements ICollection that has an Add method. By up casting to IList of Animals, it would allow subsequent code to add any type of animal which is not allowed in the "real" List collection.

那么,任何人都知道,它支持索引查找这也是协变的集合?我想不创造我自己的。

So is anyone aware of a collection that supports index lookups that is also covariant? I would like to not create my own.

谢谢! 布莱恩

推荐答案

更​​新:从.NET 4.5起就有的 IReadOnlyList&LT;出T&GT; 和<一href="http://msdn.microsoft.com/en-us/library/hh881542(v=vs.110).aspx"><$c$c>IReadOnlyCollection<out T&GT; 这两者都是协变;后者基本上是的IEnumerable&LT;出T&GT; 加上计数;前者增加了 T这个[INT指数] {获取;} 。还应当指出的是,的IEnumerable&LT;出T&GT; 是.NET 4.0起,协

Update: from .NET 4.5 onwards there is IReadOnlyList<out T> and IReadOnlyCollection<out T> which are both covariant; The latter is basically IEnumerable<out T> plus Count; the former adds T this[int index] {get;}. It should also be noted that IEnumerable<out T> is covariant from .NET 4.0 onwards.

两个名单,其中,T&GT; 和<一href="http://msdn.microsoft.com/en-us/library/vstudio/ms132474(v=vs.110).aspx"><$c$c>ReadOnlyCollection<T> (通过<一个href="http://msdn.microsoft.com/en-us/library/e78dcd75(v=vs.110).aspx"><$c$c>List<T>.AsReadOnly())实现这两个。

Both List<T> and ReadOnlyCollection<T> (via List<T>.AsReadOnly()) implement both of these.

它只能被协变,如果它只有一个 GET 索引,即

It can only be covariant if it only has a get indexer, i.e.

public T this[int index] { get; }

但是,所有主要收藏有 {获取;集;} ,这让这种尴尬的。我不知道有任何这就够了那里,但你可以的包装的它,即编写扩展方法:

But all main collections have {get;set;}, which makes that awkward. I'm not aware of any that would suffice there, but you could wrap it, i.e. write an extension method:

var covariant = list.AsCovariant();

这是一个围绕的IList℃的包装; T&GT; ,只有公开的IEnumerable&LT; T&GT; GET 索引...?应该只有几分钟工作...

which is a wrapper around an IList<T> that only exposes the IEnumerable<T> and the get indexer...? should be only a few minutes work...

public static class Covariance
{
    public static IIndexedEnumerable<T> AsCovariant<T>(this IList<T> tail)
    {
        return new CovariantList<T>(tail);
    }
    private class CovariantList<T> : IIndexedEnumerable<T>
    {
        private readonly IList<T> tail;
        public CovariantList(IList<T> tail)
        {
            this.tail = tail;
        }
        public T this[int index] { get { return tail[index]; } }
        public IEnumerator<T> GetEnumerator() { return tail.GetEnumerator();}
        IEnumerator IEnumerable.GetEnumerator() { return tail.GetEnumerator(); }
        public int Count { get { return tail.Count; } }
    }
}
public interface IIndexedEnumerable<out T> : IEnumerable<T>
{
    T this[int index] { get; }
    int Count { get; }
}

这篇关于协方差和IList的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆