詳解c# 泛型類的功能
在泛型類中,由于不知道泛型參數(shù)T是什么類型,可能是引用類型,也可能是值類型,因此不能將null等賦予泛型類型。如何對泛型對象賦初值、如何保證泛型的正確性等,以使用泛型文檔管理器為例:
文檔管理器用于從隊列中讀寫文檔。首先創(chuàng)建一個泛型管理器AddDocument()方法添加一個文檔到隊列中,IsDocumentAvailabe只讀屬性指示隊列中是否還有文檔。
public class DocumentManager<T>
{
private readonly Queue<T> documentQueue = new Queue<T>();
public void AddDocument(T doc)
{
lock (this)
{
documentQueue.Enqueue(doc);
}
}
public bool IsDocumentAvailable
{
get { return documentQueue.Count > 0; }
}
}
1、默認值
給DocumentManager<T>類添加一個GetDocument()方法,該方法以返回隊列中的一個文檔。如果隊列中存在文檔,則返回一個文檔;如果隊列中已沒有文檔,則返回默認值。但是,對于泛型T,不能將null賦予T的對象,因為無法確定它是引用類型還是值類型。在C#中,為我們提供了一個default關(guān)鍵字,泛型T的對象賦予默認值,如:引用類型為null、值類型int等為0……
public T GetDocument()
{
T doc = default(T);
lock (this)
{
if (documentQueue.Count > 0)
{
doc = documentQueue.Dequeue();
}
}
return doc;
}
2、約束
如果泛型類需要調(diào)用泛型類型中的方法,那么必須對泛型添加約束。否則,不能確保聲明的泛型類型實現(xiàn)了對應(yīng)的類型,具有相關(guān)方法。創(chuàng)建文檔類Document,其實現(xiàn)了接口IDocument:
public interface IDocument
{
string Title { get; set; }
string Content { get; set; }
}
public class Document : IDocument
{
public Document()
{
}
public Document(string title, string content)
{
this.Title = title;
this.Content = content;
}
public string Title { get; set; }
public string Content { get; set; }
}
給泛型文檔管理器DocumentManager<T>添加方法DisplayAllDocuments(),使得隊列中所有文檔的標題能展示出。在展示文檔標題前,將類型T強制轉(zhuǎn)換為IDocumnet接口,以顯示標題:
public void DisplayAllDocuments()
{
foreach (T doc in documentQueue)
{
Console.WriteLine((doc as IDocument).Title);//強制轉(zhuǎn)換
}
}
但是,如果類型T沒有實現(xiàn)接口IDocument,在對類型進行強制轉(zhuǎn)換時就會出現(xiàn)一個異常。如果對方法添加rty……catch處理,將非常損耗性能。同樣的,即使類型實現(xiàn)了接口IDocument,在進行轉(zhuǎn)換時也會出現(xiàn)性能的損耗。
那么,如果能對泛型TDocument進行約束,使得泛型類型必須實現(xiàn)接口IDocument,則不會出現(xiàn)對類型進行強制轉(zhuǎn)換時的異常。甚至不需要強制轉(zhuǎn)換,性能也將得到優(yōu)化。因此,前面的泛型文檔管理器改寫為(前面的T,改寫為TDocument,以此暗示是文檔類型):
public class DocumentManager<TDocument>
where TDocument : IDocument
{
//……
}
對于實現(xiàn)了約束的泛型文檔管理器,可以處理任何實現(xiàn)了IDocument接口的類。其DisplayAllDocuments()方法改寫為:
public void DisplayAllDocuments()
{
foreach (TDocument doc in documentQueue)
{
Console.WriteLine(doc.Title);
}
}
在其他地方調(diào)用時,可以用Document類型實例化泛型類型DocumentManager<TDocument>。因為Document實現(xiàn)了接口IDocument:
static void Main()
{
var dm = new DocumentManager<Document>();
dm.AddDocument(new Document("Title A", "Sample A"));
dm.AddDocument(new Document("Title B", "Sample B"));
dm.DisplayAllDocuments();
if (dm.IsDocumentAvailable)
{
Document d = dm.GetDocument();
Console.WriteLine(d.Content);
}
}
泛型類型支持的幾種約束:struct(結(jié)構(gòu)約束,類型T必須是值類型)、class(類約束,類型T必須是引用類型)、IFoo(類型T必須實現(xiàn)接口IFoo)、new()(構(gòu)造函數(shù)約束,類型T必須有一個無參構(gòu)造函數(shù))、TOther(類型T派生自TOther,也稱“裸類型約束”)。
泛型約束中:
- 只能為無參構(gòu)造函數(shù)定義構(gòu)造約束,不能為有任何參數(shù)的構(gòu)造函數(shù)定義構(gòu)造函數(shù)約束。
- 泛型可以有多個約束。如:public class DocumentManager<TDocument> where TDocument : IDocument,new()。
- where不能定義必須由泛型類型實現(xiàn)的運算符
3、繼承
泛型類也可以實現(xiàn)繼承,如Queue<T>里,繼承實現(xiàn)了接口IEnumerable<T>接口。泛型類型可以實現(xiàn)泛型接口,也可以派生自一個類。泛型類型可以派生自泛型基類:
class Base<T>
{
//...............
}
class Derived<T>:Base<T>
{
//...............
}
派生類可以是泛型類,也可以是非泛型類型:
abstract class Calc<T>
{
public abstract T Add(T x, T y);
public abstract T Sub(T x, T y);
}
class IncCalc: Calc<int>
{
public override int Add(int x, int y)
{
return x + y;
}
public override int Sub(int x, int y)
{
return x - y;
}
}
class DoubleCalc : Calc<double>
{
public override double Add(double x, double y)
{
return x + y;
}
public override double Sub(double x, double y)
{
return x - y;
}
}
4、靜態(tài)成員
泛型類的靜態(tài)成員只能在一個實例中共享:
class StaticDemo<T>
{
public static string Type;
}
static void Main()
{
StaticDemo<int>.Type = "int類型";
StaticDemo<object>.Type = "Object類型";
Console.WriteLine(StaticDemo<int>.Type);//輸出:int類型
}
實際上,每當用一個類型去代替泛型中的T時,都是在創(chuàng)造一個實例類型。因此,泛型類型中的靜態(tài)字段,會在不同的類型替代泛型T的實例中重新生成。這樣設(shè)計也有好處,可以為程序提供一個“泛型緩存”的概念,使用泛型的靜態(tài)成員,使它存放在緩存中,方便調(diào)用。
以上就是詳解c# 泛型類的功能的詳細內(nèi)容,更多關(guān)于c# 泛型類的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Unity?UGUI的EventSystem事件系統(tǒng)組件介紹使用
這篇文章主要為大家介紹了Unity?UGUI的EventSystem事件系統(tǒng)組件介紹使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
C#/VB.NET實現(xiàn)PPT或PPTX轉(zhuǎn)換為圖像功能
由于大多數(shù)便攜式設(shè)備支持瀏覽圖片而不支持瀏覽PowerPoint 文件,所以相比較而言,圖像對于用戶而言更加友好。本文將利用C#/VB.NET實現(xiàn)PPT或PPTX轉(zhuǎn)換為圖像功能,需要的可以參考一下2022-08-08
利用C#/VB.NET實現(xiàn)PPT轉(zhuǎn)換為HTML
利用PowerPoint可以很方便的呈現(xiàn)多媒體信息,且信息形式多媒體化,表現(xiàn)力強。但難免在某些情況下我們會需要將PowerPoint轉(zhuǎn)換為HTML格式,本文就為大家整理了轉(zhuǎn)換方法,希望對大家有所幫助2023-05-05
C#利用StreamReader和StreamWriter類處理文本的字符編碼使用示例
.NET Framework 中,StreamReader 和 StreamWriter 類提供了一些方法來處理字符編碼,這篇文章主要介紹了C#利用StreamReader和StreamWriter類處理文本的字符編碼使用示例,需要的朋友可以參考下2024-06-06

