首页 > 代码库 > C#学习之泛型功能与限制

C#学习之泛型功能与限制

在泛型类的描述中还会有时需要很多限制,例如对待一个泛型类型,在类中定义一个变量需要初始化时,不能确定是用Null还是0.

因为不能够确定它是值类型还是引用类型,这时可以用到default语句(下面有介绍)。

下面的是一个文档管理器的详细代码和必要详细的解释。

  1 //定义一个具有内容和标题属性的接口  2   3 namespace Function  4 {  5     public interface IDocument  6     {  7         string Content { set; get; }  8         string Title { set; get; }  9     } 10 } 11 //下面是文档类型的具体描述,它继承了上面的接口 12 namespace Function 13 { 14     public class Document:IDocument 15     { 16         public Document() 17         { 18  19         } 20         public Document(string title,string content) 21         { 22             this.Title = title; 23             this.Content = content; 24         } 25         public string Title 26         { 27             get; 28             set; 29         } 30         public string Content 31         { 32             get; 33             set; 34         } 35     } 36 } 37  38 //下面是文档管理器类的具体描述 39 namespace Function 40 { 41     //下面类中的where 子句的作用是要求 42     //本泛型类的T的具体类型必须是继承IDcoument接口的。 43     //如果T类型不是继承IDcoument接口,那么就不能应用到本泛型类 44     //这里的DocumentManager<T>可以实现任何继承了接口IDcoument的类型 45     //where子句还有很多其他的意义,可以看最后的图片介绍 46     public class DocumentManager<T> where T : IDocument 47     { 48         private readonly Queue<T>documentQueue=new Queue<T>(); 49         public void AddDocument(T doc) 50         { 51             //Lock语句的通俗点的意思是当有一个函数在调用本模块时,其他的函数就不能再次调用 52             //等到这里执行完毕后再被其他的使用 53            lock(this) 54             { 55                 documentQueue.Enqueue(doc); 56             } 57         } 58         public bool IsDocumentAvailable() 59         { 60             return (documentQueue.Count > 0); 61         } 62         public T GetDocument() 63         { 64             T doc = default(T);//定义doc变量,并赋予初值 65             //但是因为此处的T类型并不明确是引用类型还是值类型, 66             //赋初值时就不能明确赋予Null还是0 67             //default(T)可以根据类型自动赋值 68             lock(this) 69             { 70                 doc = documentQueue.Dequeue(); 71             } 72             return doc; 73         } 74         public void DisplayAllDocuments() 75         { 76             foreach(T doc in documentQueue) 77             { 78                 Console.WriteLine(doc.Title); 79             } 80         } 81      82     } 83 } 84 //下面是主函数 85 using System; 86 using System.Collections.Generic; 87 using System.Linq; 88 using System.Text; 89 using System.Threading.Tasks; 90  91 namespace Function 92 { 93     class Program 94     { 95         static void Main(string[] args) 96         { 97 //实例化文档管理器类,并且赋值,然后取出其中的值 98             var dm = new DocumentManager<Document>(); 99             dm.AddDocument(new Document("name1","content1"));100             dm.AddDocument(new Document("name2", "content2"));101             dm.AddDocument(new Document("name3", "content3"));102             dm.DisplayAllDocuments();103             while(dm.IsDocumentAvailable())104             {105                 Document doc = null;106                 doc = dm.GetDocument();107                 Console.WriteLine(doc.Content+" "+doc.Title);108             }109             Console.ReadKey();110             return;111         }112 113     }114 }

下面是where子句的详细介绍,也可以参看http://msdn.microsoft.com/zh-cn/library/bb384067.aspx。有详细而专业的介绍。

 
约束语句说明
where T:struct对于结构的约束,类型T必须是值类型
where T:class类约束指定类型T必须是引用类型
where T:IFoo指定类型T必须实现接口IFoo
where T:Foo指定类型T必须实现基类Foo
where T:new()这是一个构造函数的约束,指定类型T必须有一个默认的构造函数
where T1:T2这个约束也可以指定,类型T1派生自泛型类型T2,该约束也称裸类型约束

where 子句只能为默认构造函数定义构造函数约束,不能为其他构造函数定义构造函数约束。

使用泛型类还可以合并多个约束。例如where T:IFoo,new().其意义就是说T必须继承实现IFoo接口也要有默认构造函数

在where语句中只能定义基类,接口和默认构造函数

C#学习之泛型功能与限制