簡介
程序開發過程中,爲了追求代碼的可讀性和高利用性,通常我們使用很多措施來儘量提升這方面的性能。可以使用功能類來進行封裝高重用性的代碼,也可以使用方法重載、方法重寫、帶有默認值參數的函數方法等措施,除此通用措施之外,C#提供了泛型技術也極大的提升了代碼的高利用率。
泛型(Generic)可以實現您在類以及其方法等成員在聲明的時候不用考慮具體的適用的數據類型,可以聲明一個通用的功能模型,在具體的調用中在對其進行類型約束,也就是允許您延遲編寫類或方法中的編程元素的數據類型的規範,直到實際在程序中使用它的時候。個人覺得這種技術最大的優勢就是,泛型允許您編寫一個可以與任何數據類型一起工作的類或方法。
您可以通過數據類型的替代參數編寫類或方法的規範。當編譯器遇到類的構造函數或方法的函數調用時,它會生成代碼來處理指定的數據類型。下面這個簡單的實例將有助於您理解這個概念:
using System;
using System.Collections.Generic;
namespace DreamNoob.GenericApplication
{
public class MyGenericList<T>
{
private List<T> list;
public MyGenericList()
{
list = new List<T>();
}
private int length;
Public int Length
{
get{return list.Count;}
}
public T getItemAt(int index)
{
return list[index];
}
public void AddItem(T value)
{
list.Add(value);
}
public void RemoveItemAt(int index)
{
try{
list.RemoveAt(index);
}
catch
{
Console.WriteLine("數據不存在!");
}
}
}
class Tester
{
static void Main(string[] args)
{
// 聲明一個整型列表
MyGenericList<int> intList = new MyGenericList<int>();
//聲明一個字符列表
MyGenericList<char> charList = new MyGenericList<char>();
// 填充list列表
for (int c = 0; c < 8; c++)
{
intList.AddItem(c);
charList.AddItem((char)(c+97));
}
// 讀取值
Console.WriteLine("intList讀取結果:");
for (int c = 0; c < intList.Length; c++)
{
Console.Write(intList.getItemAt(c) + " ");
}
Console.WriteLine("\r\ncharList讀取結果:");
for (int c = 0; c < intList.Length; c++)
{
Console.Write(charList.getItemAt(c) + " ");
}
Console.ReadKey();
}
}
}
下面是運行結果:
通過這個簡單的例子,我們可以看見泛型在實際應用中巨大的價值了。定義泛型類的時候,不需要要考慮具體的數據類型,使用T來替代,在定義類的內部寫完整類要實現的功能邏輯,在具體的調用過程中,再使用具體的數據類型替代T即可。使用泛型,必須對泛型的特性有深刻了解,使用泛型是一種增強程序功能的技術,具體表現在以下幾個方面:
- 它有助於您最大限度地重用代碼、保護類型的安全以及提高性能。
- 您可以創建泛型集合類。.NET 框架類庫在 System.Collections.Generic 命名空間中包含了一些新的泛型集合類。您可以使用這些泛型集合類來替代 System.Collections 中的集合類。
- 您可以創建自己的泛型接口、泛型類、泛型方法、泛型事件和泛型委託。
- 您可以對泛型類進行約束以訪問特定數據類型的方法。
- 關於泛型數據類型中使用的類型的信息可在運行時通過使用反射獲取。
泛型(Generic)方法
在上面的實例中,我們已經使用了泛型類,我們可以通過類型參數聲明泛型方法。下面的程序說明了這個概念:
using System;
using System.Collections.Generic;
namespace DreamNoob.GenericApplication
{
class Program {
static string ToByte<T>(T value)
{
string result = "";
result = Convert.ToByte(value).ToString();
return result;
}
static void Main(string[] args)
{
int a;
char c;
a = 10;
c = 'I';
// 在調用之前顯示值
Console.WriteLine("Int values before calling ToByte:");
Console.WriteLine("a = {0}", a);
Console.WriteLine("Char values before calling ToByte:");
Console.WriteLine("c = {0}", c);
// 調用 ToByte()
ToByte<int>(a);
ToByte<char>(c);
// 在調用之後顯示值
Console.WriteLine("Int values after calling ToByte:");
Console.WriteLine("a = {0}", a);
Console.WriteLine("Char values after calling ToByte:");
Console.WriteLine("c = {0}", c);
Console.ReadKey();
}
}
}
當上面的代碼被編譯和執行時,它會產生下列結果:
Int values before calling swap:
a = 10
Char values before calling swap:
c = I
Int values after calling swap:
a = 10
Char values after calling swap:
c = I
泛型(Generic)委託
您可以通過類型參數定義泛型委託。例如:
delegate T CalculateDelegate<T>(T value1,T value2);
下面的實例演示了委託的使用:
using System;
using System.Collections.Generics;
namespace DreamNoob.GenericDelegateApplication
{
delegate T CalculateDelegate<T>(T value1,T value2);
class Test
{
static void Main(string[] args)
{
int a = 42,b = 55;
string s1 = "DreamNoob",s2 = " is a bird just born"
CalculateDelegate<int> intdelegte = new CalculateDelegate<int>(Add);
CalculateDelegate<string> stringdelegate = new CalculateDelegate<string>(CombineString);
int c = intdelegate(a,b);
Console.Write(c.ToString());
string s3 = stringdelegate(s1,s2);
Console.Write(s3);
Console.ReadKey();
}
static int Add(int leftvalue,int rightvalue)
{
return leftvalue+rightvalue;
}
static string CombineString( string value1,string value2)
{
return value1+value2;
}
}
}
當上面的代碼被編譯和執行時,它會產生下列結果:
97DreamNoob is a bird just born