C#實(shí)現(xiàn)協(xié)變和逆變案例
關(guān)于協(xié)變逆變,SolidMango的解釋是比較可取的。有了協(xié)變,比如,在需要返回IEnumerable<object>類型的時(shí)候,可以使用IEnmerable<string>來替代;有了逆變,比如,在需要接收IComparable<string>類型形參方法中,可以使用IComparable<object>類型實(shí)參來替代。
協(xié)變
先來體會(huì)協(xié)變。有2個(gè)具有繼承關(guān)系的父類和子類。
public class Animal
{
public string Name { get; set; }
}
public class Dog : Animal
{
public Dog(string dogName)
{
Name = dogName;
}
}現(xiàn)在有一個(gè)幫助類的方法的形參類型是父類集合IEnumerable<Animal>。
public class MyHelper
{
public void PrintAnimalNames(IEnumerable<Animal> animals)
{
foreach (var animal in animals)
{
Console.WriteLine(animal.Name);
}
}
}有了協(xié)變,可以在PrintAnimalNames方法中傳入IEnumerable<Dog>類型的實(shí)參替代IEnumerable<Animal>類型。
static void Main(string[] args)
{
List<Dog> dogs = new List<Dog>()
{
new Dog("小狗petty"),
new Dog("小狗lily")
};
//協(xié)變
IEnumerable<Animal> animals = dogs;
MyHelper myHelper = new MyHelper();
myHelper.PrintAnimalNames(animals);
Console.ReadKey();
}可見,在方法中基于基類接口類型的形參,調(diào)用該方法的時(shí)候可以傳入派生類接口類型的實(shí)參。
逆變
再來體會(huì)逆變。依然是2個(gè)具有繼承關(guān)系的父類和子類。
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Cat : Animal
{
public Cat(string catName, int catAge)
{
Name = catName;
Age = catAge;
}
}現(xiàn)在,我們想比較基類Animal的兩個(gè)實(shí)例,為此,有必要專門寫一個(gè)類讓他實(shí)現(xiàn)IComparer<Animal>接口。
public class AnimalSizeComparator : IComparer<Animal>
{
public int Compare(Animal x, Animal y)
{
if (x != null && y != null)
{
if (x.Age > y.Age)
{
return 1;
}
else if (x.Age == y.Age)
{
return 0;
}
else
{
return -1;
}
}
else
{
return -1;
}
}
}在幫助類中的方法中,針對(duì)Cat進(jìn)行比較,方法接收IComparer<Cat>類型的形參。
public class MyHelper
{
public void CompareCats(IComparer<Cat> catComparer)
{
var cat1 = new Cat("小貓1",1);
var cat2 = new Cat("小貓2",2);
if (catComparer.Compare(cat2, cat1) > 0)
{
Console.WriteLine("小貓2勝出");
}
else
{
Console.WriteLine("小貓1勝出");
}
}
}有了逆變,客戶端調(diào)用MyHelper的CompareCats方法時(shí),可以傳入IComparer<Animal>類型的實(shí)參。
IComparer<Animal> animalComparer = new AnimalSizeComparator();
MyHelper myHelper = new MyHelper();
myHelper.CompareCats(animalComparer);
Console.ReadKey(); 可見,在方法中基于派生類接口類型的形參,調(diào)用該方法的時(shí)候可以傳入基類接口類型的實(shí)參。
總結(jié):在本篇的場(chǎng)景中,派生類接口替代父類接口,稱之為協(xié)變;父類接口代替派生類接口,稱之為逆變。
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
解析錯(cuò)誤富文本json字符串(帶雙引號(hào))的快速解決方法
下面小編就為大家?guī)硪黄馕鲥e(cuò)誤富文本json字符串(帶雙引號(hào))的快速解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08
C#泛型集合類System.Collections.Generic
這篇文章介紹了C#中的泛型集合類System.Collections.Generic,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
VS2013創(chuàng)建Windows服務(wù)與調(diào)試服務(wù)的圖文方法
這篇文章主要介紹了VS2013創(chuàng)建Windows服務(wù)與調(diào)試服務(wù)的圖文方法,需要的朋友可以參考下2017-02-02

