以下,为什么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; }
}
}
这就是方差的工作方式; IEnumerable<T>
实际上是IEnumerable<out T>
,表示它是covariant;这意味着IEnumerable<Todo>
也是IEnumerable<ITodo>
,因为任何Todo
都是ITodo
。
但是,集合/列表/等是不是协变(或相反);因此这里没有隐式的可铸性。原因是:
CustomCollection<Todo>
CustomCollection<ITodo>
,则可以Add
any ITodo
class SomethingElse : ITodo
]的Todo
Todo
个集合中将有一个非Todo
ICustomCollection<T>
接口声明为协变public interface ICustomCollection<out T> : IEnumerable<T>
{
}