1.協變和抗變
在.net 4之前,泛型介面是不變的。.net 4通過協變和抗變為泛型介面和泛型委託新增了乙個重要的擴充套件。協變和抗變指對引數和返回值的型別進行轉換。例如,可以給乙個需要shape引數的方法傳送rectangle引數碼?下面用示例說明這些擴充套件的優點。
在.net中,引數型別是協變的。假定有shape和rectangle類,rectangle派生自shape基類。宣告display()方法是為了接受shape型別的物件作為其引數:
publicvoid display(shape o)
現在可以傳遞派生自shape基類的任意物件。因為rectangle派生自shape,所以rectangle滿足shape的所有要求,編譯器接受這個方法呼叫:
rectangle r = new rectangle ;display(r);
方法的返回型別是抗變的。當方法返回乙個shape時,不能把它賦予rectangle,因為shape不一定總是rectangle。反過來是可行的:如果乙個方法像getrectangle()方法那樣返回乙個rectangle,
public rectangle getrectangle();
就可以把結果賦予某個shape:
shape s = getrectangle();
在.net framework 4版本之前,這種行為方式不適用於泛型。在c# 4中,擴充套件後的語言支援泛型介面和泛型委託的協變和抗變。下面開始定義shape基類和rectangle類:
publicclass
shape
public
double height
public
override
string
tostring()
, height:
", width, height);
} }
public
class
rectangle: shape
2.泛型介面的協變
如果泛型型別用out關鍵字標註,泛型介面就是協變的。這也意味著返回型別只能是t。介面iindex與型別t是協變的,並從乙個唯讀索引器中返回這個型別:
publicinte***ce iindex
int count
}
**段variance/iindex.cs
如果對介面iindex使用了唯讀索引器,就把泛型型別t傳遞給方法,並從方法中檢索這個型別。這不能通過協變來實現-- 泛型型別必須定義為不變的。不使用out和in標註,就可以把型別定義為不變的。
iindex介面用rectanglecollection類來實現。rectanglecollection類為泛型型別t定義了rectangle:
publicclass rectanglecollection: iindex,
new rectangle ,
new rectangle
};
public
static
rectanglecollection getrectangles()
public rectangle this[int
index]
} public
intcount
} }
**段variance/rectanglecollection.cs
rectanglecollection.getrectangle()方法返回乙個實現iindex介面的rectanglecollection類,所以可以把返回值賦予iindex型別的變數rectangle。因為介面是協變的,所以也可以把返回值賦予iindex型別的變數。shape不需要rectangle沒有提供的內容。使用shapes變數,就可以在for迴圈中使用介面中的索引器和count屬性:
staticvoid
main()
}
**段variance/program.cs
3.泛型介面的抗變
如果泛型型別用in關鍵字標註,泛型介面就是抗變的。這樣,介面只能把泛型型別t用作其方法的輸入:
publicinte***ce idisplay
**段variance/idisplay.cs
shapedisplay類實現idisplay,並使用shape物件作為輸入引數:
publicclass shapedisplay: idisplay width: , height:
", s.gettype().name,
s.width, s.height);
} }
**段variance/shapedisplay.cs
建立shapedisplay的乙個新例項,會返回idisplay,並把它賦予shapedisplay變數。因為idisplay是抗變的,所以可以把結果賦予idisplay,其中rectangle派生自shape。這次介面的方法只能把泛型型別定義為輸入,而rectangle滿足shape的所有要求:
staticvoid
main()
**段variance/program.cs
C 抗變和協變
從.net3.5開始 加入了這兩個概念。在4.0中更是加強了 這裡就這兩個概念做乙個分析 委託呼叫的方法不需要與委託宣告定義的型別相同。因此可能出現協變和抗變。1.返回型別協變 方法的返回型別可以派生於委託定義的型別。在下面的示例中,委託mydelegate定義為返回delegatereturn型別...
c 協變和抗變 C 中協變與抗變(逆變)
泛型在.net 2.0中正式的引入。在使用泛型的過程中,聯絡上物件導向的繼承性。往往很容易想當然敲出類似以下 list animallst new list 顯然這樣編譯是不通過的。雖然dog和animal之間有繼承性,但是list和list這兩個類之間並沒有繼承性。如果要解決這樣的問題,用上協變與...
C 中協變抗變之我見
在.net4.0中,新加入了協變與抗變的內容,最近查了一下msdn,對它有了乙個大概的理解,希望能夠幫助到和我一樣的菜鳥。協變 協變非常類似於普通的多型性的分配,它是針對成員的返回值型別,定義時使用關鍵字out,假定您有乙個名為 base 的基類和乙個名為 derived 的派生類 ienumera...