網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
ASP.NET泛型三之使用協(xié)變和逆變實(shí)現(xiàn)類型轉(zhuǎn)換_實(shí)用技巧
作者:Darren?Ji ? 更新時(shí)間: 2022-10-08 編程語(yǔ)言".NET泛型"系列:
ASP.NET泛型一之泛型簡(jiǎn)介與基本語(yǔ)法
ASP.NET泛型二之泛型的使用方法
ASP.NET泛型三之使用協(xié)變和逆變實(shí)現(xiàn)類型轉(zhuǎn)換
ASP.NET泛型四之使用Lazy<T>實(shí)現(xiàn)延遲加載
協(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)鍵字必不可少
原文鏈接:https://www.cnblogs.com/darrenji/p/3851827.html
相關(guān)推薦
- 2022-03-03 關(guān)于使用iview table 組件中使用 tooltip 樣式覆蓋的問(wèn)題
- 2022-12-08 C++?Boost?PropertyTree示例超詳細(xì)講解_C 語(yǔ)言
- 2022-04-16 python?import模塊時(shí)有錯(cuò)誤紅線的原因_python
- 2022-09-09 python如何利用turtle繪制正方形_python
- 2023-04-18 Python中selenium獲取token的方法_python
- 2022-06-06 typescript封裝屬性、public、private、protected、constructo
- 2022-07-19 iptables限制docker端口禁止對(duì)某臺(tái)主機(jī)進(jìn)行提供服務(wù)
- 2022-08-12 Windows?Server?修改遠(yuǎn)程桌面端口的實(shí)現(xiàn)_win服務(wù)器
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支