对实现的接口进行自定义自定义收集

问题描述 投票:1回答:2

以下,为什么Todos1有效,而Todos2为什么无效?如何运作?

class Program
{
    static void Main(string[] args)
    {
        _todos = new CustomCollection<Todo>();
    }

    private static CustomCollection<Todo> _todos;

    public static IEnumerable<ITodo> Todos1
    {
        get { return _todos; }
    }

    public static ICustomCollection<ITodo> Todos2
    {
        get { return _todos; }
    }

    public class CustomCollection<T> : Collection<T>, ICustomCollection<T>
    {
    }

    public interface ICustomCollection<T> : IEnumerable<T>
    {
    }

    public interface ITodo
    {
    }

    public class Todo : ITodo
    {
        public string Description { get; set; }
    }
}
c# ienumerable
2个回答
0
投票

这就是方差的工作方式; IEnumerable<T>实际上是IEnumerable<out T>,表示它是covariant;这意味着IEnumerable<Todo>也是IEnumerable<ITodo>,因为任何Todo都是ITodo

但是,集合/列表/等是不是协变(或相反);因此这里没有隐式的可铸性。原因是:

  • 您有CustomCollection<Todo>
  • 如果可以转换为CustomCollection<ITodo>,则可以Add any ITodo
  • 包括[[not a class SomethingElse : ITodo]的Todo
  • 因此您的Todo个集合中将有一个非Todo
  • 编译器正在保护您!

  • 0
    投票
    您应该将ICustomCollection<T>接口声明为协变

    public interface ICustomCollection<out T> : IEnumerable<T> { }

    © www.soinside.com 2019 - 2024. All rights reserved.