24.3.1 《CLR via C#》 筆記9

第十二章 泛型

  1. 泛型:支持泛型值類型、泛型引用類型、泛型接口、泛型委托;允許在引用類型、值類型和接口中定義泛型方法;泛型參數變量要么稱為T,要么以T開頭

  2. 具有泛型類型參數的類型稱為開放類型,不允許構造實例;當為所有參數類型傳遞了實際參數,類型就稱為封閉類型,允許構造實例

  3. 泛型類型是類型,所以可以從其他類型派生;使用泛型類型并指定形參時,實際是定義一個新的類型(從泛型類型派生自的類型派生)。例:List<T>派生自Object,所以List<string>也派生自Object

  4. 泛型的同一性(不想讓符號<>降低可讀性時的處理)

    1. 使用class dtl : List<DateTime>,會失去同一性(typeof(dtl) != typeof( List<DateTime>))
    2. 可以使用 using dtl = System.Collections.Generic.List<DateTime>
    3. 可以直接var dtl = new List<DateTime>
  5. 代碼爆炸(CLR每新出現一種類型的實參都要編譯一次代碼)

    1. 不同程序集中同一類型只編譯一次(限定同一個domain)
    2. 所有引用類型都視為同一種實參(所有引用類型只編譯一次)
  6. 可以定義泛型接口,如IEnumerator<T>

  7. 可以定義泛型委托,如Action<T>

  8. 泛型類型參數的逆變和協變

    1. 逆變性:用in關鍵字標記的泛型參數,可以更改為它的派生類(輸入)

    2. 協變性:用out關鍵字標記的泛型參數,可以更改為它的基類(輸出)

    3. 例:定義public delegate TResult Func<in T, out TResult>(T arg);

      Func<Object, ArgumentException> fn1 = null,

      Func<String, Exception> fn2 = fn1 是合法的(因為String從Object派生,Exception是ArgumentException的基類)

      使用:Exception e = fn2(" ") ; (實參String->Object, 返回值ArgumentException->Exception)

    4. 委托和接口都可以將類型參數標記為逆變量和協變量

  9. 泛型方法,定義泛型類、結構或接口時,類中定義的方法可以使用類指定的類型參數

    例:定義了class SomeClass<T>, 類中的方法可以使用類指定的T,如定義public T SomeMethod<T>()

  10. 由于out/ref實參傳遞的變量必須具有與方法參數相同的類型,所以可以使用泛型實現。

    例:private static void Swap<T>(ref T o1, ref T o2);

  11. C#編譯器在調用泛型方法時可以進行類型推斷,在可以確定類型實參的情況下可以不用<>指定

  12. 屬性、索引器、事件、操作符方法、構造器、終結器本身不能有類型參數,但是可以在泛型類中定義,從而使用泛型類的類型參數

  13. 泛型可驗證性:編譯代碼時需要確定代碼適用于當前或已有或將來可能定義的任何類型,比如調用T.ToString(),對所有類型都有ToString()方法,所以代碼合法

  14. 使用where關鍵字指定約束

    1. 約束可以應用于泛型類和泛型方法,不能用于重載(不能基于類型參數名稱或約束重載,也不允許為重寫方法的類型指定約束)
    2. 主要約束:主要約束指非密封類的一個引用類型(不包括Object, Array, Delegate, MulticastDelegate, ValueType, Enum, Void),能有零個或一個
    3. 特殊主要約束:class,指引用類型;struct,指值類型
    4. 次要約束:指接口類型,能有零個或多個
    5. 構造器約束:指擁有公共無參構造器的非抽象類型
  15. 其他可驗證性問題

    1. 不能將泛型變量轉型為其他變量(除非轉成與約束兼容的類型)
    2. 不能將泛型變量設為null(除非泛型類型被約束成引用類型)
    3. 可以將泛型類型變量與null比較(==或!=),(雖然值類型不能與null比較(因為永遠不會null),但是約束成值類型后,代碼能通過編譯,但不執行if邏輯,只生成永遠為true的分支的代碼)
    4. 同一泛型類型的兩個變量,如果不能肯定是引用類型,則不能比較(T a,b;判斷 a==b)
    5. 不能將操作符(+、-、*、/)用于泛型變量(不能編譯)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/712561.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712561.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712561.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java畢業設計 基于SpringBoot vue 社區團購系統

Java畢業設計 基于SpringBoot vue 社區團購系統 SpringBoot vue 社區團購系統 功能介紹 前端用戶: 首頁 圖片輪播 商品信息 商品分類展示 搜索 商品詳情 點我收藏 添加到購物車 立即購買 我要開團 去參團 評論 公告資訊 資訊詳情 登錄 注冊 個人中心 更新信息 點我充值 我的訂…

Mysql筆記3

1、快速創建表 原理&#xff1a; 將一個查詢結果當做一張表新建 這個可以完成表的快速復制 create table emp2 as select * from emp; mysql> select * from emp2; ---------------------------------------------------------------------- …

【vscode提取函數快捷鍵】提取函數,減少大方法的復雜度

在 Visual Studio Code 中&#xff0c;提取函數的快捷鍵取決于你所使用的編程語言和安裝的插件。以下是一些常用的快捷鍵組合&#xff0c;可以用來在 Visual Studio Code 中提取函數&#xff1a; 執行以下步驟來提取函數&#xff1a; 選中要提取的代碼塊。右鍵單擊選中的代碼…

System Verilog學習筆記(十二)——數組(2)

System Verilog學習筆記&#xff08;十二&#xff09;——數組&#xff08;2&#xff09; 動態數組 在編譯時不會為其定制尺寸&#xff0c;而是在仿真運行時來確定動態數組一開始為空&#xff0c;需要使用new[ ]來為其分配空間聲明方式 int dyn[],d2[]; //聲明了兩個動態數組…

git之遠程操作

一.分布式版本控制系統 分布式版本控制系統通常也有?臺充當“中央服務器”的電腦&#xff0c;但這個服務器的作?僅僅是?來?便“交換”?家的修改&#xff0c;沒有它?家也?樣?活&#xff0c;只是交換修改不?便?已。有了這個“中央服務器”的電腦&#xff0c;這樣就不怕…

ChatGPT學習第四周

&#x1f4d6; 學習目標 ChatGPT實踐操作 通過實際操作和練習&#xff0c;加深對ChatGPT功能的理解。 項目&#xff1a;創建一個ChatGPT應用案例 設計一個基于ChatGPT的小項目&#xff0c;將理論應用于實踐。 ?? 學習活動 學習資料 《萬字干貨&#xff01;ChatGPT 從零完…

[C++核心編程](一):內存分區

目錄 代碼區 全局區 棧區 堆區 new操作符 不同區域存放的數據&#xff0c;賦予不同的生命周期&#xff0c;給予開發人員更大的靈活編程。 代碼區 存放二進制代碼&#xff0c;由操作系統管理未執行程序&#xff08;.exe&#xff09;前已經存在共享&#xff0c;對頻繁執行…

達夢數據庫查詢語句內存溢出問題解決

背景&#xff1a;達夢數據庫使用過程中&#xff0c;某天突然服務宕機&#xff0c;導致各類后端服務無法注冊到nacos上&#xff0c;重啟之后nacos正常啟動&#xff0c;可執行一條兩千多條數據量的連表查詢時間很長&#xff0c;甚至會報錯&#xff0c;經查看日志發現在查詢過程中…

【C語言】常見的動態內存管理錯誤

前言 上一篇介紹了C語言中 動態內存管理函數&#xff0c;本片講解的是 在我們使用動態內存管理時 常見的錯誤&#xff0c;一起來看看吧~ 歡迎關注個人主頁&#xff1a;逸狼 創造不易&#xff0c;可以點點贊嗎~ 如有錯誤&#xff0c;歡迎指出~ 目錄 1.對NULL指針的解引?操作 錯…

什么是前端框架中的數據綁定(data binding)?有哪些類型的數據綁定?

聚沙成塔每天進步一點點 ? 專欄簡介 前端入門之旅&#xff1a;探索Web開發的奇妙世界 歡迎來到前端入門之旅&#xff01;感興趣的可以訂閱本專欄哦&#xff01;這個專欄是為那些對Web開發感興趣、剛剛踏入前端領域的朋友們量身打造的。無論你是完全的新手還是有一些基礎的開發…

YOLOv5白皮書-第Y4周:common.py文件解讀

YOLOv5白皮書-第Y4周:common.py文件解讀 YOLOv5白皮書-第Y4周:common.py文件解讀0.導入需要的包和基本配置1.基本組件1.1 autopad1.2 Conv1.3 Focus1.4 Bottleneck1.5 BottleneckCSP1.6 C31.7 SPP1.8 Concat1.9 Contract、Expand 2.重要類2.1 非極大值抑制&#xff08;NMS&…

vue3中的基本語法

目錄 基礎素材 vue3的優化 使用CompositionAPI理由 1. reactive() 函數 2. ref() 函數 2.1. ref的使用 2.2. 在 reactive 對象中訪問 ref 創建的響應式數據 3. isRef() 函數 4. toRefs() 函數 5. computed() 5.1. 通過 set()、get()方法創建一個可讀可寫的計算屬性 …

函數——遞歸6(c++)

角谷猜想 題目描述 日本一位中學生發現一個奇妙的 定理&#xff0c;請角谷教授證明&#xff0c;而教授 無能為力&#xff0c;于是產生了角谷猜想。 猜想的內容&#xff1a;任給一個自然數&#xff0c; 若為偶數則除以2&#xff0c;若為奇數則乘 3加1&#xff0c;得到一個新的…

git命令整理

一、什么是git Git 是為了幫助管理 Linux 內核開發而開發的一個開放源碼的版本控制軟件。 分布式管理系統&#xff0c;可以快速的查看文件各個版本的改動。比如在第5行加了一個單詞“Linux”&#xff0c;在第8行刪了一個單詞“Windows”。而圖片、視頻這些二進制文件&#xf…

PyTorch深度學習快速入門

PyTorch深度學習快速入門 1.PyTorch環境配置及安裝2.python編輯器的選擇、安裝、配置&#xff08;pycharm、JupyTer安裝&#xff09;3.為什么torch.cuda.is_available()返回false4.python學習中兩大法寶函數&#xff08;也可用在pytorch&#xff09;5.pycharm和jupyter&#xf…

golang goroutine 如何退出?

上一講說到調度器將maingoroutine推上舞臺&#xff0c;為它鋪好了道路&#xff0c;開始執行runtime.main函數。這一講&#xff0c;我們探索maingoroutine以及普通goroutine從執行到退出的整個過程。 //Themaingoroutine. funcmain(){ //gmaingoroutine&#xff0c;不再是g0了 …

Python列表中添加刪除元素不走彎路

1.append() 向列表中添加單個元素&#xff0c;一般用于尾部追加 list1 ["香妃", "乾隆", "賈南風", "趙飛燕", "漢武帝"]list1.append("周瑜") print(list1) # [香妃, 乾隆, 賈南風, 趙飛燕, 漢武帝, 周瑜]…

STM32標準庫——(14)I2C通信協議、MPU6050簡介

1.I2C通信 I2C 通訊協議(Inter&#xff0d;Integrated Circuit)是由Phiilps公司開發的&#xff0c;由于它引腳少&#xff0c;硬件實現簡單&#xff0c;可擴展性強&#xff0c; 不需要USART、CAN等通訊協議的外部收發設備&#xff0c;現在被廣泛地使用在系統內多個集成電路(IC)間…

【LeetCode每日一題】【BFS模版與例題】863.二叉樹中所有距離為 K 的結點

BFS的基本概念 BFS 是廣度優先搜索&#xff08;Breadth-First Search&#xff09;的縮寫&#xff0c;是一種圖遍歷算法。它從給定的起始節點開始&#xff0c;逐層遍歷圖中的節點&#xff0c;直到遍歷到目標節點或者遍歷完所有可達節點。 BFS 算法的核心思想是先訪問當前節點的…

計算機網絡_2.2物理層下面的傳輸媒體

2.2物理層下面的傳輸媒體 一、傳輸媒體的分類二、導向型傳輸媒體1、同軸電纜2、雙絞線3、光纖&#xff08;1&#xff09;光纖通信原理&#xff08;2&#xff09;光纖組成&#xff08;4&#xff09;多模光纖與單模光纖對比&#xff08;5&#xff09;光纖的波長與規格&#xff08…