我只需要再次使用協變類型修飾符out
。我有一個類的泛型類型,並想添加一個out
但VS告訴我,這隻能在接口上實現。爲什麼我需要協方差接口(輸出類型)?
但是,爲什麼我只能在界面上使用out
修飾符?
我幫助自己創建了我的類的接口副本,但這對於我來說似乎有點奇怪,因爲我只有一個接口,所以我可以使用此修飾符。
我只需要再次使用協變類型修飾符out
。我有一個類的泛型類型,並想添加一個out
但VS告訴我,這隻能在接口上實現。爲什麼我需要協方差接口(輸出類型)?
但是,爲什麼我只能在界面上使用out
修飾符?
我幫助自己創建了我的類的接口副本,但這對於我來說似乎有點奇怪,因爲我只有一個接口,所以我可以使用此修飾符。
確保類的定義實際上是協變性是非常困難的。編譯器更容易確保接口實際上是協變的。
對於一個類,僅僅使用一個使用泛型類型的字段立即強制泛型參數是不變的,因爲就編譯器而言,該值可以被讀取和修改。儘管支持差異的類可能是,但在實踐中,需要向開發人員實際使用它的約束將會非常困難,而不僅僅是創建包裝界面。
讓我們考慮一個簡單的例子:
public interface IWrapper<out T>
{
T Value { get; }
}
public class Wrapper<T> : IWrapper<T>
{
public Wrapper(T value)
{
Value = value;
}
public T Value { get; private set; }
}
上面顯示是不是相對於T
協變(除非您將它轉換爲界面)的類。它接受類型爲T
的輸入值(通過構造函數)。只有因爲構造函數沒有通過接口暴露,接口才能夠協變。
Lippert先生的經典(和正確的)迴應將是「因爲沒有人執行」,並跟隨「成本不能證明附加價值」。 –
@DStanley:雖然這是真的,但這裏還有其他技術原因。如果這個類不是一成不變的,那麼你將如何安全地使用變體T?如果T是「in」,那麼類型T的字段不能被讀取,並且如果T是「out」,那麼不能寫入類型T的字段;字段你可以不讀或不寫無用的功能。協方差對於不可變類非常有用,其中所有字段都是隻讀的;他們可以寫在構造函數中。 *這是我關於成本和價值觀的適用點。 –