協(xié)變和逆變使我們在處理類層次結構時更加靈活。
在學習協(xié)變和逆變之前,請看以下類層次結構:
public class Small { } public class Big: Small { } public class Bigger : Big { }
根據(jù)上面的示例類,Small 是 Big 的基類,而Big 是 Bigger 的基類。這里要記住的一點是,派生類將始終具有比基類更多的東西,因此基類比派生類要小。
現(xiàn)在,看以下初始化:
如上所示,基類可以容納派生類,但派生類不能容納基類。換句話說,一個實例即使要求很小也可以接受大,但是如果要求很大就不能接受小。
現(xiàn)在,讓我們了解協(xié)變和逆變。
協(xié)變使您能夠傳遞派生類型,其中需要基類型。協(xié)變就像同類型的方差。基類和其他派生類被認為是向基類型添加額外功能的同類類。因此,協(xié)變允許您在需要基類的地方使用派生類(如果需要小類,則 rule: 可以接受大類)。
協(xié)變可以應用于委托,泛型,數(shù)組,接口等。
委托中的協(xié)變允許委托方法的返回類型具有靈活性。
public delegate Small covarDel(Big mc); public class Program { public static Big Method1(Big bg) { Console.WriteLine("Method1"); return new Big(); } public static Small Method2(Big bg) { Console.WriteLine("Method2"); return new Small(); } public static void Main(string[] args) { covarDel del = Method1; Small sm1 = del(new Big()); del= Method2; Small sm2 = del(new Big()); } }
Method1 Method2
如您在上面的示例中看到的那樣,委托期望返回的類型為 Small(基類),但是我們?nèi)匀豢梢苑峙浞祷谺ig(派生類)的Method1以及具有與委托期望的簽名相同的Method2。
因此,協(xié)變允許您將方法分配給具有較少派生返回類型的委托。
將Contravariane(逆變)應用于參數(shù)。 Cotravariance(逆變) 允許將基類參數(shù)分配給希望派生類參數(shù)的委托的方法。
繼續(xù)上面的示例,添加具有與委托不同的參數(shù)類型的Method3:
delegate Small covarDel(Big mc); class Program { static Big Method1(Big bg) { Console.WriteLine("Method1"); return new Big(); } static Small Method2(Big bg) { Console.WriteLine("Method2"); return new Small(); } static Small Method3(Small sml) { Console.WriteLine("Method3"); return new Small(); } static void Main(string[] args) { covarDel del = Method1; del += Method2; del += Method3; Small sm = del(new Big()); }
Method1 Method2 Method3
如您看到的,Method3具有Small類的參數(shù),而委托則期望Big類的參數(shù)。 不過,您可以將Method3與委托一起使用。
您還可以按如下所示的相同方法使用協(xié)變和逆變。
delegate Small covarDel(Big mc);class Program { static Big Method4(Small sml) { Console.WriteLine("Method3"); return new Big(); } static void Main(string[] args) { covarDel del = Method4; Small sm = del(new Big()); } }
Method4