我想我真的需要是變化的一個簡單的解釋 - 逆變和協方差 - 在C#泛型的情況下,我已經找到here和here:
錯誤消息並沒有真正使我說,但現在我會總結:
逆變
通用類,當然是一個類的模板而不是類定義,可以使用逆向使用的關鍵字。甲逆變類允許從基類的實例分配到一個派生類實例即邊境牧羊犬=犬
public interface AllowAssignmentsFromBaseToDerived<in T>
協方差
泛型類可以使用出關鍵字進行協變。甲協變類允許從派生類實例分配到基類的實例,即狗=邊境牧羊犬
public interface AllowAssignmentsFromDerivedToBase<out T>
方差被支承用於數組類型,因爲C#1.0和委託類型,因爲C#2.0,以及因爲C#通用類型參數4.0。
很高興能有更多的回覆來覆蓋我已經錯過的更多觀點,仍然感覺有點不知情。
更多信息從here解禁:
如何創建變型通用接口和委託自己?
out關鍵字將類型參數標記爲協變,並且 關鍵字將其標記爲逆變。到 兩個最重要的規則要記住:
您可以標記一個泛型類型參數的協變如果只是 作爲方法的返回類型,而不是作爲一種形式化方法 參數。
反之亦然,你可以,如果它 只是用來作爲一種形式化方法的參數,而不是用作 方法的返回類型標記類型逆變。
interface IVariant<out R, in A>
{
// These methods satisfy the rules.
R GetR();
void SetA(A sampleArg);
R GetRSetA(A sampleArg);
// And these don’t.
// A GetA();
// void SetR(R sampleArg);
// A GetASetR(R sampleArg);
}
此外,如果擴展一個變種通用接口是默認不變。您需要根據需要指定In或Out。
最後,我的解釋將是遠遠不夠的嘗試Eric Lippert's blog
因爲'IList'是不變的(或者更具體地說,它不是協)在其類型參數。如果該方法的聲明返回類型是,例如,「IEnumerable>'',您可以返回'List >'。 –
換句話說:問題是關於什麼可以傳遞到列表的方法有衝突的規則。 'IList>'聲明你可以用任何'IEnumerable '調用'Add',但是'List >'說它必須是一個HashSet。但是,您可以創建一個'List >',並將HashSets添加到它。 –
nmclean