C# 为什么将具有泛型参数的接口强制转换为具有较少约束的同一接口不起作用?
我有以下情况:C# 为什么将具有泛型参数的接口强制转换为具有较少约束的同一接口不起作用?,c#,generics,types,casting,C#,Generics,Types,Casting,我有以下情况: 专用IHandle映射(IHandle句柄) 其中T:ICommand { 返回(i手柄)手柄; } 该代码给出了运行时错误。 但似乎IHandle比IHandle更通用(因为中的T:ICommand约束)。我不明白为什么类型系统不能允许这种类型转换。我该怎么办呢?假设它是IList而不是IHandle。以下操作不起作用: IList<Bar> bars = new List<Bar>(); IList<Foo> foos =
专用IHandle映射(IHandle句柄)
其中T:ICommand
{
返回(i手柄)手柄;
}
该代码给出了运行时错误。
但似乎
IHandle
比IHandle
更通用(因为中的T:ICommand
约束)。我不明白为什么类型系统不能允许这种类型转换。我该怎么办呢?假设它是IList
而不是IHandle
。以下操作不起作用:
IList<Bar> bars = new List<Bar>();
IList<Foo> foos = (IList<Foo>)bars;
public class Foo { }
public class Bar : Foo { }
IList条=新列表();
IList foos=(IList)条;
公共类Foo{}
公共类栏:Foo{}
因为如果您尝试调用foos.Add(newfoo()),会发生什么代码>?基础类型是一个Bar
列表,它不能接受任何旧的Foo
,否则它将不再是一个Bar
列表。其他人可能仍然有对它的引用,需要以typeBar
的形式遍历它的所有元素。因此,接口必须是精确的类型
这应该解决标题中的问题,即为什么cast不能在普通接口上工作。至于“你应该如何处理它”,如果你保证你的接口只输出通用参数类型的东西,而从不将它们作为输入,你可以像其他人建议的那样,通过使接口协变来使它工作。假设它是IList
而不是IHandle
。以下操作不起作用:
IList<Bar> bars = new List<Bar>();
IList<Foo> foos = (IList<Foo>)bars;
public class Foo { }
public class Bar : Foo { }
IList条=新列表();
IList foos=(IList)条;
公共类Foo{}
公共类栏:Foo{}
因为如果您尝试调用foos.Add(newfoo()),会发生什么代码>?基础类型是一个Bar
列表,它不能接受任何旧的Foo
,否则它将不再是一个Bar
列表。其他人可能仍然有对它的引用,需要以typeBar
的形式遍历它的所有元素。因此,接口必须是精确的类型
这应该解决标题中的问题,即为什么cast不能在普通接口上工作。至于“你应该怎么做”,如果你保证你的接口只输出泛型参数类型的东西,而从不将它们作为输入,你可以像其他人所建议的那样通过使接口协变来使它工作。具体错误是什么?@Clay07g无法将IncrementHandler类型的对象强制转换为IHandle`1[ICommand]“.InvalidCastException只有当IHandle
在T
上是协变的,这意味着它只返回T
,从不将其作为参数或用于设置属性,定义必须是IHandle
具体错误是什么?@Clay07g无法将IncrementHandler类型的对象强制转换为”键入“IHandle`1[ICommand]”。只有当IHandle
在T
上是协变的时,InvalidCastException才会起作用,这意味着它只返回T
,从不将其作为参数或用于设置属性,并且定义必须是IHandle