網站首頁 編程語言 正文
前言
這篇文章簡單說說C#中的協變和逆變。
在C#編程中,由于存在類型之間的強制轉換,很容易會出現所謂的類型可變性說法,存在協變、逆變、不變三種。
就比如前一篇文章介紹的泛型概念,如果創建了泛型類型的實例,編譯器會接受泛型類型聲明以及類型參數來創建構造類型。但是在日常使用過程中,我們可能會將派生類型分配給基類型的變量,有時候會出現錯誤。
這里就存在一個賦值兼容性問題。
每一個變量都有一種類型,可以將派生類對象的實例賦值給基類變量(好比之前子類聲明的變量可以賦值給父類聲明的變量一樣)。
如下所示:
class People { public int Age = 27; } class AhuiPeople : People { }
?
People ahui = new People(); People people = new AhuiPeople(); Console.WriteLine("Age:"+people.Age); Console.ReadKey();
協變和逆變
我們按照同樣的邏輯,在泛型委托中進行這種強類型的轉換,會發現即使基類和派生類之間可以進行正常的轉換,但是委托之間不能進行轉換會出現異常錯誤提示。
具體如下代碼所示:
delegate T AgeDelegate<T>(); static AhuiPeople GetAge() { return new AhuiPeople(); }
在轉換過程中,委托的具體用法,但是這樣子編譯器提示錯誤。
AgeDelegate<AhuiPeople> ahui = GetAge; AgeDelegate<People> people = ahui;
錯誤提示
這就是上面解釋的那樣子,基類和派生類之間可以進行轉換但是委托之間未存在關聯,無法進行強制類型的轉換。
那么想解決這個問題就引入了協變來解決。
如果派生類只是用于輸出值,那么這種結構化的委托有效性之間的常數關系叫做協變,可通過主動告知編譯器我們的期望,使用Out關鍵字標記委托聲明中的類型參數。
delegate T AgeDelegate<out T>();
修改成這樣子后,上面錯誤演示的代碼編譯器就可以正常編譯通過了。
上面簡單介紹了協變,那么接下來我們來看逆變是什么。
其實逆變就是在委托中既要聲明委托類型,也要在委托方法中有實參。
這種在期望傳入基類時允許傳入派生對象的特性叫做逆變。 逆變使用關鍵字in來標記。
具體如下代碼所示:
delegate void AgeDelegate<in T>(T p); static void GetAge(People p) { Console.WriteLine(p.Age); }
AgeDelegate<People> ahui = GetAge; AgeDelegate<AhuiPeople> people = ahui; people(new AhuiPeople()); Console.WriteLine(); Console.ReadKey();
輸出結果
既然協變和逆變可以使用在委托上,那么接口上也可以使用,此時也需要使用out和in關鍵字。
總結
原文鏈接:https://www.cnblogs.com/netxiaohui/p/15865060.html
相關推薦
- 2022-06-14 web項目中golang性能監控解析_Golang
- 2023-03-26 CSS填充和寬高詳解_基礎教程
- 2022-11-03 C++高精度算法的使用場景詳解_C 語言
- 2022-07-19 簡單認清深拷貝和淺拷貝
- 2022-08-01 MongoDB創建與刪除數據庫_MongoDB
- 2022-06-01 python?嵌套型partials的使用_python
- 2022-07-17 代碼解析python標準庫logging模塊_python
- 2022-09-29 go日志庫logrus的安裝及快速使用_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支