博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#泛型-泛型类
阅读量:5955 次
发布时间:2019-06-19

本文共 4851 字,大约阅读时间需要 16 分钟。

为什么需要泛型:

CLR 2.0的一个新特性是泛型。在.CLR 1.0 中,要创建一个灵活的类或方法,但该类或方法在编译期间不知道使用什么类,就必须以 Object 类为基础。而 Object 类在编译期间没有类型安全性,因此必须进行强制类型转换。另外,给值类型使用Object类会有性能损失。

 

性能 

第一、泛型的一个主要优点是性能.避免装箱,拆箱

   例如:ArrayList方法Add(Value),value值只要继承object均可以添加进去,但是需要:装箱 ;foreach时需要拆箱

  (从值类型转换为引用类型称为装箱反之称拆箱)

 

第二、类型安全

  例如:List<T>中,泛型类型 T若 定义了允许使用的类型int,那么Add(value)方法中value只允许int值类型

 

第三、二进制代码重用(泛型类可以定义一次,用许多不同的类型实例化)

  例如:List<int> list = new List<int>(); list.Add(1); 

              List<string> stringList = new List<string>(); stringList.Add("string");

  泛型类型可以在一种语言中定义,在另一种.NET语言中使用。 

 

 

案例:

DocumentManager

/* * 说明:使用泛型文档管理器的示例  *  * 注意:  * default关键字根据上下文可以有多种含义。switch语句使用 default定义默认情况。在泛型中,根 * 据泛型类型是引用类型还是值类型,default关键字用于将泛型类型初始化为 null或 0。  * * 创建:2012-04-26 */using System;using System.Collections.Generic; using System.Text;using System.Collections;namespace DocumentManager{    //类约束指定,类型 T必须执行接口IDocument    public class DocumentManager
where T :IDocument { private readonly Queue
documentQueue = new Queue
(); ///
/// AddDocument()方法将一个文档添加到 /// 队列中。如果队列不为空,IsDocumentAvailable只读属性就返回 true /// ///
public void AddDocument(T doc) { lock (this) { documentQueue.Enqueue(doc); } } ///
/// 队列中有值返回True否则False /// public bool IsDocumentAvailable { get { return documentQueue.Count > 0; } } ///
/// 给类型 T指定默认值 /// ///
public T GetDocument() { T doc = default(T); //泛型默认值:使用 default 关键字 lock (this) { doc = documentQueue.Dequeue(); } return doc; } ///
/// 展示所有文档 /// public void DisplayAllDocument() { foreach (T doc in documentQueue) { Console.WriteLine(((IDocument)doc).Title); } } }}

Document

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace DocumentManager{    public class Document : IDocument    {        public Document()         {        }        public string Title { get; set; }        public string Content { get; set; }        public Document(string title, string content)        {            this.Title = title;            this.Content = content;        }    }}

TDocument

namespace DocumentManager{    public class TDocument : IDocument    {        public TDocument()         {        }        public string Title { get; set; }        public string Content { get; set; }        public TDocument(string title, string content)        {            this.Title = title;            this.Content = content;        }    }}

 

/* * 如果泛型类需要调用泛型类型上的方法,就必须添加约束  *  */using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace DocumentManager{    public interface IDocument    {        string Title { get; set; }        string Content { get; set; }    }}

 

Program

class Program    {        static void Main(string[] args)        {            //DocumentManager
tm = new DocumentManager
(); //tm.AddDocument(new TDocument("Title TDocument","Content TDocument")); //tm.DisplayAllDocument(); DocumentManager
dm = new DocumentManager
(); dm.AddDocument(new Document("Title A", "Sample A")); dm.DisplayAllDocument(); dm.AddDocument(new Document("Title B", "Sample B")); dm.DisplayAllDocument(); if (dm.IsDocumentAvailable) { Document d = dm.GetDocument(); Console.WriteLine(d.Content); } } }

 

 

结果:建议先自己心算下……

 

 

 

 

(是不是和你的意愿不一致?那再好好看看代码)

 

 

 

 

 

 

 

注意:

 

default关键字根据上下文可以有多种含义。switch语句使用 default定义默认情况。在泛型中,根
据泛型类型是引用类型还是值类型,default关键字用于将泛型类型初始化为 null或 0。

 

如果泛型类需要调用泛型类型上的方法,就必须添加约束 。格式: where+约束类型

 

约    束  说    明 
where T : struct  使用结构约束,类型 T必须是值类型 
where T : class  类约束指定,类型 T必须是引用类型 
where T : IFoo  指定类型T必须执行接口 IFoo
where T : Foo  指定类型T必须派生于基类 Foo
where T : new()  这是一个构造函数约束,指定类型 T必须有一个默认构造函数 
where T : U 

这个约束也可以指定,类型 T1 派生于泛型类型 T2。该约束也称为裸类型约

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

 

 

静态成员 

泛型类的静态成员需要特别关注。泛型类的静态成员只能在类的一个实例中共享
//泛型类的静态成员需要特别关注。泛型类的静态成员只能在类的一个实例中共享            //由于对一个string类型和一个int类型使用了 StaticDemo
类,所以存在两组静态字段: StaticDemo
.x = 1; StaticDemo
.x = 11; StaticDemo
.x = 111; Console.WriteLine(StaticDemo
.x); Console.WriteLine(StaticDemo
.x);
public class StaticDemo
{ public static int x; }

 

 

 

 

 

 

 

                                                                                                                                                         引自《C#高级编程》

 

 

转载地址:http://vaexx.baihongyu.com/

你可能感兴趣的文章
hello world
查看>>
CentOS 7 配置yum本地base源和阿里云epel源
查看>>
python 学习导图
查看>>
生成树
查看>>
(MYSQL) Unknown table 'a' in MULTI DELETE的解决办法
查看>>
作为一个程序员必备的素质
查看>>
Webpack入门教程十四
查看>>
104种***清除方法
查看>>
Exchange 2016 之移动设备邮箱策略
查看>>
zookeeper使用简介及注意事项
查看>>
python练习题1
查看>>
mha-环境搭建
查看>>
rabbitMq
查看>>
ubuntu mysql lessons
查看>>
Linux命令基础
查看>>
Hibernate查询技术(2)
查看>>
https被修改成http排查过程
查看>>
常用端口号
查看>>
[转] 深入理解React 组件状态(State)
查看>>
组队赛3
查看>>