C# 将自定义集合强制转换为实现的接口
在下面的例子中,为什么Todos1有效,而Todos2无效?如何让它工作C# 将自定义集合强制转换为实现的接口,c#,generics,ienumerable,C#,Generics,Ienumerable,在下面的例子中,为什么Todos1有效,而Todos2无效?如何让它工作 class Program { static void Main(string[] args) { _todos = new CustomCollection<Todo>(); } private static CustomCollection<Todo> _todos; public static IEnumerable<ITodo
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实际上是IEnumerable,意思是它是协变的;这意味着任何IEnumerable的东西都是IEnumerable的,因为任何Todo都是ITodo 然而,集合/列表/etc不是协变或逆变的;所以这里没有隐含的可铸造性。原因是: 你有自己的收藏 如果这是可铸造到CustomCollection,您可以添加任何ITodo 包括课堂上的一些事情:ITodo这不是一个待办事项 所以在你的待办事项集合中有一个非待办事项
编译器正在保护你 这就是方差的工作原理;IEnumerable实际上是IEnumerable,意思是它是协变的;这意味着任何IEnumerable的东西都是IEnumerable的,因为任何Todo都是ITodo 然而,集合/列表/etc不是协变或逆变的;所以这里没有隐含的可铸造性。原因是: 你有自己的收藏 如果这是可铸造到CustomCollection,您可以添加任何ITodo 包括课堂上的一些事情:ITodo这不是一个待办事项 所以在你的待办事项集合中有一个非待办事项 编译器正在保护你 您应该将ICustomCollection接口声明为 公共接口ICustomCollection:IEnumerable { } 否则它是不变的,您只能将其强制转换为用于声明的相同Todo类型,而不是ITodo接口 IEnumerable已经具有协变泛型类型参数T,因此第一个属性按预期工作。您应该将ICustomCollection接口声明为 公共接口ICustomCollection:IEnumerable { } 否则它是不变的,您只能将其强制转换为用于声明的相同Todo类型,而不是ITodo接口 IEnumerable已经具有协变泛型类型参数T,因此第一个属性按预期工作。因此,它必须是接口ICustomCollection:IEnumerable才能工作;对吗?所以,它必须是接口ICustomCollection:IEnumerable才能工作;正当