国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

.NET泛型03,泛型類型的轉(zhuǎn)換,協(xié)變和逆變

2019-11-17 03:01:59
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

.NET泛型03,泛型類型的轉(zhuǎn)換,協(xié)變和逆變

協(xié)變(Convariant)和逆變(Contravariant)的出現(xiàn),使數(shù)組、委托、泛型類型的隱式轉(zhuǎn)換變得可能。 子類轉(zhuǎn)換成基類,稱之為協(xié)變;基類轉(zhuǎn)換成子類,稱之為逆變。.NET4.0以來(lái),支持了泛型接口的協(xié)變和逆變。

泛型協(xié)變

如果子類泛型隱式轉(zhuǎn)換成基類泛型,使用泛型協(xié)變。

有這樣的2個(gè)基類和派生類。

public class Animal    {        public virtual void Write()        {            Console.WriteLine("我是基類");        }    }    public class Dog : Animal    {        public override void Write()        {            Console.WriteLine("我是小小狗");        }    }

為了讓派生類Dog隱式轉(zhuǎn)換成基類Animal,先定義支持協(xié)變的泛型接口。

//支持協(xié)變的接口    public interface IFactory<out T>    {        T Create();    }

再實(shí)現(xiàn)這個(gè)接口。

public class Factory<T> : IFactory<T>    {        public T Create()        {            return (T)Activator.CreateInstance<T>();        }    }

客戶端調(diào)用。

class PRogram    {        static void Main(string[] args)        {            IFactory<Dog> dogFactory = new Factory<Dog>();            IFactory<Animal> animalFactory = dogFactory; //協(xié)變            Animal animal = animalFactory.Create();            animal.Write();            Console.ReadKey();        }    }

運(yùn)行輸出:我是小小狗

以上,我們可以看出:● 協(xié)變后,父類的方法完全由子類替代,父類原先的方法不復(fù)存在● 泛型接口中的out關(guān)鍵字必不可少

泛型逆變

關(guān)于通知的一個(gè)接口。

public interface INotification    {        string Message { get; }    }

關(guān)于通知接口的抽象實(shí)現(xiàn)。

public abstract class Notification : INotification    {        public abstract string Message { get; }    }

關(guān)于通知抽象類的具體實(shí)現(xiàn)。

public class MailNotification : Notification    {        public override string Message        {            get { return "你有郵件了~~"; }        }    }

接下來(lái),需要把通知的信息發(fā)布出去,需要一個(gè)發(fā)布通知的接口INotifier,該接口依賴INotification,大致INotifier<INotification>,而最終顯示通知,我們希望INotifier<MailNotification>,INotifier<INotification>轉(zhuǎn)換成INotifier<MailNotification>,這是逆變,需要關(guān)鍵字in。

public interface INotifier<in TNotification> where TNotification : INotification    {        void Notify(TNotification notification);    }

實(shí)現(xiàn)INotifier。

public class Notifier<TNotification> : INotifier<TNotification> where TNotification : INotification    {        public void Notify(TNotification notification)        {            Console.WriteLine(notification.Message);        }    }

客戶端調(diào)用。

class Program    {        static void Main(string[] args)        {            INotifier<INotification> notifier = new Notifier<INotification>();            INotifier<MailNotification> mailNotifier = notifier;//逆變            mailNotifier.Notify(new MailNotification());            Console.ReadKey();        }    }

運(yùn)行輸出:你有郵件了~~

以上,我們可以看出:● INotifier的方法Notify()的參數(shù)類型是INotification,逆變后把INotification類型參數(shù)隱式轉(zhuǎn)換成了實(shí)現(xiàn)類MailNotificaiton?!?泛型接口中的in關(guān)鍵字必不可少

參考資料:《你必須知道的.NET(第2版)》,作者王濤。

".NET泛型"系列包括:

.NET泛型01,為什么需要泛型,泛型基本語(yǔ)法

.NET泛型02,泛型的使用

.NET泛型03,泛型類型的轉(zhuǎn)換,協(xié)變和逆變

.NET泛型04,使用Lazy<T>實(shí)現(xiàn)延遲加載


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 泸西县| 南昌市| 安平县| 江阴市| 白水县| 德州市| 巴青县| 景德镇市| 新乡市| 定日县| 鲁甸县| 庄浪县| 安塞县| 老河口市| 成都市| 平遥县| 保德县| 南和县| 南澳县| 文安县| 焦作市| 渝中区| 新乡县| 茂名市| 应城市| 华坪县| 柳江县| 隆德县| 长白| 乌兰县| 龙南县| 华安县| 乌审旗| 龙州县| 龙口市| 顺义区| 桓台县| 枝江市| 防城港市| 四会市| 洛阳市|