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语句中只能定义基类,接口和默认构造函数

时间: 2024-11-09 22:06:08

C#学习之泛型功能与限制的相关文章

IOS开发-OC学习-常用功能代码片段整理

IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是在做与URL有关的功能时,需要在Info.plist中添加一段代码进而实现让网址完成从Http到Https的转换,以及其他的一些功能. 在从一个新手到逐渐学会各种功能.代码.控件.方法如何使用的过程中,也在逐渐积累一些知识,但是一次总不会把这些东西都深刻记住并完全理解.所以在这儿记录下这些东西,用来

.net学习之泛型、程序集和反射

一.泛型1.CLR编译时,编译器只为MyList<T>类型产生“泛型版”的IL代码——并不进行泛型的实例化,T在中间只充当占位符.例如:MyList 类型元数据中显示的<T> 2.执行的时候,当JIT编译器第一次遇到MyList<int>时,将用int替换“范型版”IL代码与元数据中的T—进行泛型类型的实例化.例如 :Main函数中显示的<int> 3.什么是泛型泛型是具有占位符(类型参数)的类.方法.结构.接口 4.泛型类的继承public class F

C#学习之泛型继承和静态成员

想要理解这里有必要先将泛型类学习充分.这里讲解的是泛型类继承类的类型和静态成员. 在前面C#学习之泛型中,创建的LinkList<T>类实现了IEnumerable<T>接口. 即泛型类也可以实现泛型的接口,也可派生自一个类.泛型类也可以派生自泛型基类. public class Base<T> { } public class Derived<T>:Base<T> { } 也可以指定基类的类型,可以执行某些特定操作 public class D

树莓派学习笔记——GPIO功能学习

树莓派学习笔记——GPIO功能学习

Linux学习—LVM快照功能

LVM快照功能--我们知道LVM能够通过增减PE的数量来弹性调整文件系统的大小,除此之外,LVM还有另外一个重要的功能,LV磁盘快照,就是通过快照的功能将此时的文件系统信息记录下来,以后对该文件系统操作的时候,当该文件系统的数据变化的时候,我们可以利用快照将文件系统恢复至当时的状态. 目录 LV的快照原理 创建快照 利用快照恢复系统 一.LV的快照(snapshot)原理 左边的图表示,LVM会在VG上预留一定的区域作为快照区,原本lv中存放着数据,同时快照区存放着lv中元数据,因此快照区大小不

每天学习一个小功能:java文件上传

====(1.)第一种.利用普通缓冲流进行文件上传 ① 前端 注意: 1.指定表单类型为文件上传表单 :enctype="multipart/form-data"  2.提交方式必须为:post3.表单中,存在文件域 的表单元素 <form name="frm_test" action="${pageContext.request.contextPath }/shangchuan" method="post" encty

Java编程思想学习(十一) 泛型

1.概要 generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. 泛型能在定义类,接口和方法时将类型(类和接口)作为参数.和方法声明时的形式参数很类似,都是为了在不同的输入时重用相同的代码.不同的是形式参数输入的是值而泛型是类型. 2.为什么使用泛型 1.编译时更加强的(Stronger)类型检测java编译器对泛型代码进行强类型检

unity3d中设计模式的学习&lt;一&gt;:泛型单例

单例是游戏开发中比较常见的设计模式,虽然针对的功能不同,但是有一些功能还是共有的,代码也不少,如果能放在一个基类里面是最好不过了,但是单例里需要有个instance功能来返回当前对象,所以这个功能必须是static的,没办法直接继承,之前看了<面向对象的游戏开发>这本书里,使用的是泛型,于是我实验了几次 现在我们就来实现这个较为简单的单例泛型: public class Singleton<T> : MonoBehaviour where T: MonoBehaviour //因为

C#学习之泛型

什么泛型? 泛型是程序设计语言的一种特性.允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明.各种程序设计语言和其编译器.运行环境对泛型的支持均不一样.将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型.泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念. 为什么要使用泛型? 通常我们在开发的时候会碰到这样的情况:一个方法实现的功能都是一样的(比如说保存一个对象),但是我们传递的参数类型不一样而已,如果按照一般来讲都会去拷贝一份方法把传递的参