好吧,一步一步来。
iPoppable<Lion> lions = new Group<Lion>();
作品,因为Group
实现iPoppable
和泛型参数T
是一样的。
iPoppable<Animal> animals = lions;
作品,因为他们两人都是iPoppable
和Lion
从Animal
派生。更正式地说,这是协方差的一个例子。
将实例化为更多派生类型参数的对象分配给实例化派生类型参数较少的对象。分配兼容性被保留。
来自Microsoft Docs。
Group<Lion> lions2 = lions;
不起作用,因为您将接口类型分配给类类型。 iPoppable
只是说lions
有Lion Pop();
方法,没有更多!通过说Group<Lion> lions2 = lions;
你声称,lions2
是一个全功能的Group
对象,它将有所有方法和属性Group
类。这是不一定是真的,这就是为什么编译器抱怨。
您可以说
Group<Lion> lions2 = (Group<Lion>)lions;
因为你知道一个事实,即特别lions
,虽然类型为iPoppable
其实Group
帮助编译器。
为了说明编译器害怕什么,请参阅以下代码片段。
interface iPoppable<out T>
{
T Pop();
}
interface iPushable<in T>
{
void Push(T ag_t);
}
class Program
{
static void Main()
{
// Here, we know the truth, so we cast
iPoppable<bool> group = new Group<bool>();
Group<bool> group2 = (Group<bool>)group; // Possible
// What about here? We also convert iPoppable to Group...
iPoppable<bool> notGroup = new NotGroup<bool>();
Group<bool> notGroup2 = (Group<bool>)notGroup; // Bad... Compiler was right...
notGroup2.HelloGroup = true; // HA! Runtime exception.
// That's what compiler was worrying about.
// System.InvalidCastException: Unable to cast object of
// type 'NotGroup`1[System.Boolean]' to type 'Group`1[System.Boolean]
}
}
class Group<T> : iPoppable<T>, iPushable<T>
{
public void Push(T ag_t) { }
public T Pop() { return default(T); }
public bool HelloGroup { get; set; }
}
class NotGroup<T> : iPoppable<T>, iPushable<T>
{
public void Push(T ag_t) { }
public T Pop() { return default(T); }
public bool HelloNotGroup { get; set; }
}
对于初学者,您的“Group”分类中的签名不正确。 Pop应该返回'T'类型的对象,而不是void。你还需要研究协变*和*反变换。 – lintmouse
谢谢。刚刚纠正。是的。我只是读了他们两个。 –