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

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

.NET泛型01,為什么需要泛型,泛型基本語法

2019-11-14 16:34:07
字體:
供稿:網(wǎng)友

.NET泛型或許是借鑒于C++泛型模版,借助它可以實現(xiàn)對類型的抽象化、泛型處理,實現(xiàn)了類型和方法之間的解耦。一個最經(jīng)典的運用是在三層架構(gòu)中,針對不同的領(lǐng)域模型,在基接口、基類中實現(xiàn)針對各個領(lǐng)域模型的泛型處理。

 

本篇主要包括:
■ 為什么需要泛型
    ※ 不用泛型
    ※ 使用泛型
    ※ 泛型的運行時本質(zhì)
■ 泛型語法
■ 典型的泛型類

 

  為什么需要泛型

  不用泛型

來看一個比較類型的方法。

public class Calculator    {        public static bool AreEqual(int value1, int value2)        {            return value1 == value2;        }    }


在客戶端調(diào)用。

class PRogram    {        static void Main(string[] args)        {            bool result = Calculator.AreEqual(1, 2);            if (result)            {                Console.WriteLine("相等");            }            else            {                Console.WriteLine("不等");            }            Console.ReadKey();        }    }


運行結(jié)果:不等

 

  不用泛型的缺點一:不是類型安全

如果我們想使用現(xiàn)在的方法來比較字符串類型。

bool result = Calculator.AreEqual("A", "B");

這時,看到編譯器報錯。從這點來看,AreEqual()方法不是類型安全的方法,當(dāng)輸入string類型,編譯器就會報錯。

 

如果把AreEqual()方法的參數(shù)類型改成object,編譯器就不再報錯。

public class Calculator    {        public static bool AreEqual(object value1, object value2)        {            return value1 == value2;        }    }

以上,運行也正常。

 

  不用泛型的缺點二:裝箱與拆箱導(dǎo)致性能降低

現(xiàn)在,對于AreEqual(object value1, object value2),從方法本身來講是沒有問題的,但在客戶端調(diào)用的時候,比如我們還是想比較值類型。

bool result = Calculator.AreEqual(1, 2);

在運行時,當(dāng)整型值類型參數(shù)1和2傳遞、賦值給AreEqual(object value1, object value2)中的引用類型參數(shù)value1和value2的時候,發(fā)生了一次"裝箱"操作。而當(dāng)把引用類型轉(zhuǎn)換成值類型的時候,又會發(fā)生一次"拆箱"操作,這導(dǎo)致性能的降低。

 

  使用泛型

把AreEqual()改成泛型方法。

public class Calculator    {        public static bool AreEqual<T>(T value1, T value2)        {            return value1.Equals(value2);        }    }

 

于是,在客戶端可以這樣:

bool result = Calculator.AreEqual<string>("A", "A"); bool result = Calculator.AreEqual<int>(5, 3);

 

由此,使用泛型的好處有:
1、實現(xiàn)了方法和類型的解耦。
2、不會造成類型轉(zhuǎn)換,規(guī)避了因裝箱于拆箱引起的性能問題。
3、泛型保證了類型的絕對安全。

 

當(dāng)然,還可以把T的位置放在類上:

public class Calculator<T>    {        public static bool AreEqual(T value1, T value2)        {            return value1.Equals(value2);        }    }

 

然后這樣使用:

bool result = Calculator<string>.AreEqual("A", "A"); bool result = Calculator<int.AreEqual(1, 2);


 

  泛型的運行時本質(zhì)

CLR中有專門的IL指令支持泛型操作。
→初次編譯時,生成IL代碼和元數(shù)據(jù),T只是類型占位符,在編譯時不進行實例化
→JIT編譯時,以實際類型替換元數(shù)據(jù)中的T占位符
→將元數(shù)據(jù)轉(zhuǎn)換為本地代碼

 

  泛型語法

class MyArray<T> where T : Student, new(){    private T[] _items;    public T myData;    public MyArray()    {        myData = default(T);    }    public void Add(T item)    {}}

創(chuàng)建泛型實例要指定實際的數(shù)據(jù)類型:
MyArray<Int32> myArr = new MyArray<Int32>();

 

值類型的默認(rèn)值為0,引用類型的默認(rèn)值為null,使用泛型默認(rèn)值:
myData = default(T);

 

泛型約束:
T : 基類名,表示必須是基類名的派生類
T :new(), 表示必須具有無參構(gòu)造函數(shù),new()約束必須放在最后面
T :struct, 表示必須是值類型
T :class, 表示必須是引用類型
T :接口名,表示必須實現(xiàn)該接口,或?qū)崿F(xiàn)該接口的接口

 

泛型類本質(zhì)上仍然是一個類,依然可以繼承:

internal class GenericeComparer<T> : Comparer<T> where T : IComparable<T>class MyArray<T> : ArrayList

 

  典型的泛型類

在System.Collections.Generic命名空間和System.Collections.ObjectModel中,定義了不同的泛型類和泛型接口,這些泛型多為集合類。

List<T> 對應(yīng)ArrayList集合類
SortedList<TKey, TValue> 對應(yīng)SortedList集合類
Queue<T> 先進先出的集合類
Stack<T> 后進先出的集合類
Collection<T> 自定義泛型集合的基類
Dictionary<TKey, TValue> 對應(yīng)于Hashtable集合類

 

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

 

".NET泛型"系列包括:

.NET泛型01,為什么需要泛型,泛型基本語法

.NET泛型02,泛型的使用

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

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


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 白沙| 丰都县| 莒南县| 缙云县| 怀化市| 淄博市| 安阳市| 砚山县| 宝丰县| 长丰县| 高台县| 松潘县| 乌拉特后旗| 常宁市| 班戈县| 宁都县| 古蔺县| 石棉县| 吉首市| 文水县| 南和县| 兴和县| 喀什市| 海丰县| 长汀县| 和政县| 巴彦县| 华坪县| 眉山市| 饶平县| 泌阳县| 德庆县| 临安市| 大田县| 通河县| 昭觉县| 清苑县| 滁州市| 临夏市| 白河县| 金湖县|