3.泛型类的功能
在创建泛型类时,还需要一些其它C#关键字。例如,不能把null赋予泛型类型。此时,如下一节所述,可以使用default关键字。如果泛型类型不需要Object类的功能,但需要调用泛型类上的某些特定方法,就可以定义约束。
本节讨论如下主题:
*默认值
*约束
*继承
*静态成员
首先介绍一个使用泛型文档管理器的示例。文档管理器用于从队列中读写文档。先创建一个控制台项目DocumentManager,并添加DocumentManager<T>类。AddDocument()方法将一个文档添加到队列中。如果队列不为空,IsDocumentAvailable只读属性就返回true。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Wrox.ProCSharp.Generics { 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。但是,不能把null赋予泛型类型。原因是泛型类型也可以实例化为值类型,而null只能用于引用类型。为了解决这个问题,可以使用default关键字。通过default关键字,将null赋予引用类型,将0赋予值类型。
public T GetDocument() { T doc = default(T); lock (this) { doc = documentQueue.Dequeue(); } return doc; }
注:default关键字根据上下文可以有多种含义。在switch语句中使用default定义默认情况。在泛型中,根据泛型类型是引用类型还是值类型,泛型default用于将泛型类型初始化为null或0。
2.约束
如果泛型类型需要调用泛型类型中的方法,就必须添加约束。
对于DocumentManager<T>,文档的所有标题应在DisplayAllDocuments()方法中显示。Document类实现带有Title和Content属性的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 Content { get; set; } public string Title { get; set; } }
要使用DocumentManager<T>类显示文档,可以将类型T强制转为IDocument接口,以显示标题。