日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

泛型的优势

發布時間:2023/12/1 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 泛型的优势 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


假設需要一個兩個整形變量交換的函數,我們很快就可以嗒嗒嗒嗒的敲出下面的 Swap 函數:

?



void Swap(ref int lhs, ref int rhs)

{

??? int temp = lhs;

??? lhs = rhs;

??? rhs = temp;

}

?

隨著項目進展,我們發現,需要用到 Swap 函數的不僅是整形,變量 還有字符串,于是我們我又嗒嗒嗒嗒的重載 Swap 函數如下:

?



void Swap(ref string lhs, ref string rhs)

{

??? string temp = lhs;

??? lhs = rhs;

??? rhs = temp;

}

?

接下來的開發中,我們又發現還有自定義的結構體,類等等等等都要用到 Swap 函數。如果我們為每一種類型都實現一個相應的 Swap 函數的話,各個版本的 Swap 函數數據類型不同外,其它完完全全一樣。也就是說,項目中存在大量的代碼重復。能不能之實現一個能夠適用于不同數據類型的 Swap 函數,消除這種代碼冗余,從而減少工作量,提高開發效率呢?

類型轉換
在 C# 中 所有的類型都直接或間接的繼承自 System.Object 類。換句話說,所有的類型都可以轉換為 Object 類。這為我們前面的問題提供了一個解決方案——實現一個以 Object 為類型參數的 Swap 函數。其實現如下:

?



void Swap(ref object lhs, ref object rhs)

{

??? object temp = lhs;

??? lhs = rhs;

??? rhs = temp;

}

?

調用的代碼如下:



//a, b 為要傳入 Swap 函數的變量

object objA = a;

object objB = b;

?

Swap(ref objA, ref objB);

?

//T 為變量 a 和 b 的數據類型

a = (T)objA;

b = (T)objB;

?

這一實現利用類型轉換有效的重用了 Swap 的代碼,但有兩點不足。

?

首先是性能問題。每次調用 Swap 函數前,需要對其參數進行一次向上的轉型;調用完之后,又要對其進行一次向下的轉型。如果需要多次調用 Swap 函數(比如在一個很大的循環中),轉型帶來的開銷是想當可觀的,特別是當參數為值類型的時候。

?

第二是,無法提供編譯時類型檢查。下面的例子雖然能通過編譯,但運行時會出現異常:

?



string a? = “This is a string”;

int b = 0;

?

object objA = a;

object objB = b;

?

Swap(ref objA, ref objB);?????????????? //可以編譯

?

a = (string)objA;?????????????? //出現運行時異常

b = (ing)objB;

?

針對以上兩點不足,C# 2.0 提出了泛型。

泛型
泛型是C# 2.0 提供的延遲類和函數中數據類型的定義,直到客戶代碼聲明或實例化該數據類型。

?

泛型版的 Swap 函數實現如下

?



void Swap<T>(ref T lhs, ref T rhs)

{

??? T temp = lhs;

??? lhs = rhs;

??? rhs = temp;

}??????? ?

?
泛型集合中的 <T>是obj類型
上例中的類型參數 T 可以實例化為任意數據類型。相對于通過類型轉換重用 Swap 函數,它且不需要類型轉換,有效的提高性能。而且,它還能提供編譯時類型檢查。調用語法與普通函數調用完全一樣。

泛型的優勢
從上面例子可以看出,使用泛型具有如下三點優勢:

?

??????? 避免重復代碼,最大化代碼重用

??????? 避免無謂的類型轉換,提高性能

??????? 提供編譯時類型檢查,具有類型安全性

C# code

// 在三角符號里寫入類型參數T
public class GenericList<T>
{
// Node為非泛型類,作為GenericList<T>的嵌套類
private class Node
{
// 在非泛型構造函數中使用T
public Node(T t)
{
next
= null;
data
= t;
}

private Node next;
public Node Next
{
get { return next; }
set { next = value; }
}

// T作為私有成員的數據類型
private T data;

// T作為屬性的返回類型
public T Data
{
get { return data; }
set { data = value; }
}
}

private Node head;

// 構造函數
public GenericList()
{
head
= null;
}

// T 作為方法的參數類型
public void AddHead(T t)
{
Node n
= new Node(t);
n.Next
= head;
head
= n;
}

public IEnumerator<T> GetEnumerator()
{
Node current
= head;

while (current != null)
{
yield return current.Data;
current
= current.Next;
}
}
}




下面的代碼示例演示客戶端代碼如何使用泛型 GenericList <T> 類來創建整數列表。只需更改類型參數,即可方便地修改下面的代碼示例,創建字符串或任何其他自定義類型的列表:

C# code

class TestGenericList
{
static void Main()
{
// int 是類型變量
GenericList<int> list = new GenericList<int>();

for (int x = 0; x < 10; x++)
{
list.AddHead(x);
}

foreach (int i in list)
{
System.Console.Write(i
+ " ");
}
System.Console.WriteLine(
"\n完成");
}
}

泛型也在用在類里,可以對參數進行約束而對于new約束而言有點特殊


public?class?Dictionary<K,V>?where?K:?IComparable
{
????
public?void?Add(K?key,?V?value)
????
{
????????
????????
if?(key.CompareTo(x)?<?0)?{}
????????
????}

}


這樣就保證了任何為K類型參數提供的類型都實現了IComparable接口。所以我們的key就可以使用CompareTo方法了。

如果我們在使用時提供了沒有實現IComparable接口的類型,就會出現編譯時錯誤。

對于new()約束,大家可能有一個誤解,以為使用了new約束之后,在創建對象時與非泛型的版本是一致的:

publicclassTester<T>
whereT:new()
{
publicTester()
{
t=newT();//等同于非泛型版本的new?例如objecto=newobject();?
}

privateTt;

}
  事實上,使用new關鍵字的作用只是讓編譯器在泛型實例化之處,檢查所綁定的泛型參數是否具有無參構造函數:

Tester<SomeType>t=newTester<SomeType>();
//此處編譯器會檢查SomeType是否具有無參構造函數。若沒有則會有compileerror

?

轉載于:https://www.cnblogs.com/dewin/archive/2009/06/28/1512868.html

總結

以上是生活随笔為你收集整理的泛型的优势的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。