好吧,一步一步來。
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
謝謝。剛剛糾正。是的。我只是讀了他們兩個。 –