最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#高級(jí)靜態(tài)語言效率利器之泛型詳解

 更新時(shí)間:2023年02月27日 11:19:19   作者:微小冷  
所謂泛型,就是創(chuàng)建一個(gè)函數(shù),對(duì)所有數(shù)據(jù)類型都生效。這篇文章就來帶大家深入了解一下C#中高級(jí)靜態(tài)語言效率利器——泛型的使用,需要的可以參考一下

引入

所謂泛型,就是創(chuàng)建一個(gè)函數(shù),對(duì)所有數(shù)據(jù)類型都生效。最常見的例子就是運(yùn)算符,畢竟1+1=2,1.0+1.0=2.0,足以看出+是對(duì)多種數(shù)據(jù)類型起作用的。

但是,如想創(chuàng)建一個(gè)函數(shù)add(int a, int b),那么輸入add(1.0, 1.0)是肯定要報(bào)錯(cuò)的,VS直接就給標(biāo)紅了。

泛型的出現(xiàn),就很好地解決了這個(gè)尷尬的問題

T add<T>(T a, T b) 
{
    dynamic d1 = a;
    dynamic d2 = b;
    return (T)(d1 + d2);
}

Console.WriteLine(add<int>(1, 1));
Console.WriteLine(add<double>(1.0, 1.0));

上面代碼中,T表示某種數(shù)據(jù)類型,在調(diào)用函數(shù)add時(shí),根據(jù)add后面的<>加以聲明。

但如果就此就寫return a+b顯然也是不行的,因?yàn)?這種運(yùn)算符并沒有對(duì)T進(jìn)行重載,編輯器并不會(huì)允許兩種未知的類型相加。

這個(gè)時(shí)候就需要用到dynamic,用來讓編輯器放棄類型檢查,將任何可能發(fā)生的錯(cuò)誤都留給運(yùn)行階段。

最后,運(yùn)行結(jié)果為

2
2

類型約束

dynamic用著確實(shí)爽,但后果就是責(zé)任自負(fù),這玩意要是用在團(tuán)隊(duì)協(xié)作的場(chǎng)合,簡(jiǎn)直就是災(zāi)難,畢竟并非所有對(duì)象都可以駕馭加法。

所以,C#的泛型,是可以被約束的泛型,關(guān)鍵就是where,將上述代碼寫為

T add<T>(T a, T b) where T : struct{
    dynamic d1 = a;
    dynamic d2 = b;
    return (T)(d1 + d2);
}

where T : struct表示T必須是數(shù)值類型的一種,所以編譯器的類型檢查仍會(huì)發(fā)揮作用,在調(diào)用add時(shí),如果T不是數(shù)值類型,就會(huì)報(bào)錯(cuò)。

C#一共有5種約束方案,列表如下

類別條件
structT必須是值類型
classT必須是引用類型
new()T必須有無參數(shù)的構(gòu)造函數(shù)
基類名T必須是基類或派生自基類
接口名T必須是指定接口
裸類型

 不同類型的約束,或相同類型不同種類的約束,一般是可以混用的,如果不能混用,編譯器會(huì)提醒。比如struct幾乎不能和其他類型混用。如果new()參與了約束,則放在最后。

子類泛型

除了函數(shù)可以采用泛型,類當(dāng)然也可以,不僅可以,而且還能繼承。

class MyList<T>
{
    public T[] a;
    public MyList(){}       //無參數(shù)的構(gòu)造函數(shù),用于繼承
    public MyList(int n){
        a = new T[n];
    }
    public T this[int index]{
        get => a[index];
        set => a[index] = value;
    }

???????}

MyList相當(dāng)于是給數(shù)組套了一層殼,其構(gòu)造函數(shù)并不存在什么難以理解的地方,唯一有些問題的可能是下面的索引器public T this[int index],這種寫法可以實(shí)現(xiàn)方括號(hào)形式的索引。

可以測(cè)試一下

var a = new MyList<int>(5);
for (int i = 0; i < 5; i++)
{
    a[i] = i;
    Console.WriteLine(a[i]);
}

結(jié)果就不粘貼了,接下來新建一個(gè)子類

class MyStack<T> : MyList<T>
{
    public MyStack(int n)
    {
        a = new T[n];
    }
    public T Pop()
    {
        T p = a[a.Length- 1];
        a = a[0..(a.Length-1)];
        return p;
    }
}

然后測(cè)試一下

var a = new MyStack<int>(3);
for (int i = 0; i < 3; i++)
{
    a[i] = i;
}

for (int i = 0; i < 3; i++)
{
    Console.WriteLine(a.Pop());
}

結(jié)果為

2
1
0

常用的泛型數(shù)據(jù)結(jié)構(gòu)

C#通過泛型定義了很多數(shù)據(jù)結(jié)構(gòu),例如在講解switch...case時(shí)提到的字典

Dictionary<int, string> card = new Dictionary<int, string>
{
    {1,"A" },
    {11, "J" },
    {12, "Q" },
    {13, "K" }
};

這種<U, V>的寫法,正是泛型的特點(diǎn),其中U, V就是可以隨意聲明的變量。如果查看字典的類型參數(shù),可以發(fā)現(xiàn)其定義方法是這樣的

public class Dictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, ... where TKey : notnull

考慮到本節(jié)并不是為了將面向?qū)ο?,所以字典繼承的那一大坨類就省略了,關(guān)鍵是where Tkey:notnull,也就是說,字典對(duì)鍵值對(duì)的要求只有一個(gè),就是鍵不得為null。

除了字典之外,還有一些常見的數(shù)據(jù)結(jié)構(gòu)采用了泛型,列表如下,沒事兒可以練習(xí)練習(xí)。

數(shù)據(jù)結(jié)構(gòu)說明常用方法
List<T>泛型列表Add, Remove, RemoveAt
LinkedList<T>雙端鏈表AddFirst, AddLast, RemoveFirst, RemoveLast
Queue<T>先進(jìn)先出列表Enqueue, Dequeue
Stack<T>棧,先進(jìn)后出Push, Pop

泛型委托

委托,是函數(shù)的函數(shù);泛型,可以讓函數(shù)的參數(shù)類型更加靈活,二者結(jié)合在一起,就是更加靈活的函數(shù)的函數(shù),即泛型委托。

只要學(xué)過了泛型和委托,那么對(duì)泛型委托將毫無理解上的難度,回想前面定義的運(yùn)算符委托

delegate int Op(int a, int b);

再回想定義泛型時(shí)的<T>,那么泛型委托可以非常簡(jiǎn)單地定義出來

delegate T Op<T>(T a, T b);

然后就可以根據(jù)委托,建立一個(gè)泛型函數(shù)

T add<T>(T a, T b)
{
    dynamic d1 = a;
    dynamic d2 = b;
    return (T)(d1 + d2);
}
var addTest = new Op<int>(add<int>);
//也可以省略add后的<int>,寫成下面的形式
//var addTest = new Op<int>(add);
Console.WriteLine(addTest(3, 5));

運(yùn)行之后控制臺(tái)出現(xiàn)了8,就是這么簡(jiǎn)單。

到此這篇關(guān)于C#高級(jí)靜態(tài)語言效率利器之泛型詳解的文章就介紹到這了,更多相關(guān)C#泛型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Unity實(shí)現(xiàn)OCR文字識(shí)別功能

    Unity實(shí)現(xiàn)OCR文字識(shí)別功能

    這篇文章主要介紹了通過Unity接入百度AI接口,實(shí)現(xiàn)OCR文字識(shí)別功能,文中的實(shí)現(xiàn)步驟講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定的參考價(jià)值,需要的可以了解一下
    2022-01-01
  • C#操作windows系統(tǒng)進(jìn)程的方法

    C#操作windows系統(tǒng)進(jìn)程的方法

    這篇文章介紹了C#操作windows系統(tǒng)進(jìn)程的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • DevExpress之ChartControl用法實(shí)例總結(jié)

    DevExpress之ChartControl用法實(shí)例總結(jié)

    這篇文章主要介紹了DevExpress之ChartControl用法實(shí)例總結(jié),需要的朋友可以參考下
    2014-08-08
  • C#實(shí)現(xiàn)線性搜索算法

    C#實(shí)現(xiàn)線性搜索算法

    線性搜索算法是一種基本的搜索算法,通過逐個(gè)比較元素來查找目標(biāo)元素,學(xué)習(xí)線性搜索算法有助于培養(yǎng)算法思維和編程能力,對(duì)于初學(xué)者來說是一種重要的算法訓(xùn)練,感興趣的可以了解一下
    2024-10-10
  • C#程序中session的基本設(shè)置示例及清除session的方法

    C#程序中session的基本設(shè)置示例及清除session的方法

    這篇文章主要介紹了C#程序中session的基本設(shè)置示例及清除session的方法,是C#入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-04-04
  • C#實(shí)現(xiàn)身份證實(shí)名認(rèn)證接口的示例代碼

    C#實(shí)現(xiàn)身份證實(shí)名認(rèn)證接口的示例代碼

    身份證實(shí)名認(rèn)證,即通過姓名和身份證號(hào)校驗(yàn)個(gè)人信息的匹配程度,廣泛應(yīng)用于金融、互聯(lián)網(wǎng)等多個(gè)領(lǐng)域,本文主要介紹了C#實(shí)現(xiàn)身份證實(shí)名認(rèn)證接口的示例代碼,感興趣的可以了解一下
    2024-09-09
  • C#主線程堵塞問題的解決方案

    C#主線程堵塞問題的解決方案

    這篇文章主要介紹了C#主線程堵塞問題的解決方案,在C#中,異步方法和async/await關(guān)鍵字是用來解決主線程阻塞的有效方式,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-03-03
  • C#實(shí)現(xiàn)Modbus通信功能的示例詳解

    C#實(shí)現(xiàn)Modbus通信功能的示例詳解

    Modbus作為一種開放且廣泛采用的通信協(xié)議,在實(shí)現(xiàn)設(shè)備間數(shù)據(jù)交換方面發(fā)揮著至關(guān)重要的作用,它不僅支持多種物理層接口(如RS-232,?RS-485,?以及以太網(wǎng)),還因其簡(jiǎn)單易用的特點(diǎn)而被大家所青睞,本文通過實(shí)際示例介紹如何在C#項(xiàng)目中輕松實(shí)現(xiàn)Modbus通信功能
    2024-11-11
  • Unity實(shí)現(xiàn)虛擬搖桿

    Unity實(shí)現(xiàn)虛擬搖桿

    這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)虛擬搖桿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 在C#中獲取端口號(hào)與系統(tǒng)信息的高效實(shí)踐

    在C#中獲取端口號(hào)與系統(tǒng)信息的高效實(shí)踐

    在現(xiàn)代軟件開發(fā)中,尤其是系統(tǒng)管理、運(yùn)維、監(jiān)控和性能優(yōu)化等場(chǎng)景中,了解計(jì)算機(jī)硬件和網(wǎng)絡(luò)的狀態(tài)至關(guān)重要,C# 作為一種廣泛應(yīng)用的編程語言,提供了豐富的 API 來幫助開發(fā)者獲取計(jì)算機(jī)的硬件信息和網(wǎng)絡(luò)狀態(tài),本篇博客將帶你深入探索如何在 C# 中高效獲取端口號(hào)和系統(tǒng)信息
    2025-01-01

最新評(píng)論

久治县| 山东| 基隆市| 宁海县| 共和县| 永州市| 逊克县| 德庆县| 汉沽区| 泰州市| 武隆县| 肃宁县| 东阳市| 旬邑县| 阿鲁科尔沁旗| 射阳县| 桃源县| 宝兴县| 民乐县| 潞城市| 固阳县| 龙井市| 丰城市| 澳门| 乐亭县| 邵武市| 贺州市| 奇台县| 英超| 苗栗市| 马龙县| 宁强县| 八宿县| 化州市| 柘荣县| 房山区| 师宗县| 封丘县| 涿州市| 中方县| 迁安市|