泛型类的定义类似于一般的类,只是要使用泛型类型声明。之后就可以在类中把泛型类型用作成员字段,或方法的参数类型。在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。这些限制称为约束。约束是使用 where 关键字指定的。

约束

说明

T:结构

类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。

T:类

类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。

T:new()

类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。

T:<基类名>

类型参数必须是指定的基类或派生自指定的基类。

T:<接口名称>

类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。

T:U

为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束。

简单约束说明实例:
  1.     //值类型struct|引用类型class约束
  2.     public struct Text
  3.     {
  4.     }
  5.     public class Test<T>
  6.         where T : struct
  7.     {
  8.         //T在这里是一个值类型
  9.     }
  10.     public class Check
  11.     {
  12.         Test<Text> test = new Test<Text>();
  13.     }
  14.     //new()约束
  15.     public class Text
  16.     {
  17.         public Text() { }//无参数的构造函数
  18.     }
  19.     public class Test<T>
  20.         where T : new()
  21.     {
  22.         //可以在其中使用T t = new T();
  23.     }
  24.     public class Check
  25.     {
  26.         Test<Text> test = new Test<Text>();
  27.     }
  28.     //基类约束
  29.     public class Text
  30.     {
  31.         public void Add() { }
  32.     }
  33.     public class Test<T>
  34.         where T : Text//T继承至Text
  35.     {
  36.         //可以在类型为T的变量上调用Add()方法
  37.     }
  38. //接口约束见下面实例
自定义泛型实例:
  1. //源代码下载路径:http://media.wiley.com/product_ancillary/41/07645753/DOWNLOAD/Ch10.zip
  2. namespace Wrox.ProCSharp.Generics
  3. {
  4.     using System;
  5.     using System.Threading;
  6.     using System.Collections.Generic;
  7.     public interface IDocument
  8.     {
  9.         string Title { get;}
  10.         string Content { get;}
  11.     }
  12.     public class Document : IDocument
  13.     {
  14.         private string title;
  15.         public string Title
  16.         {
  17.             get { return title; }
  18.         }
  19.         private string content;
  20.         public string Content
  21.         {
  22.             get { return content; }
  23.         }
  24.         public Document(string title, string content)
  25.         {
  26.             this.title = title;
  27.             this.content = content;
  28.         }
  29.     }
  30.     /// <summary>
  31.     /// 定制泛型类【使用接口约束】
  32.     /// </summary>
  33.     public class ProcessDocuments<TDocument, TDocumentManager>
  34.         where TDocument : IDocument
  35.         where TDocumentManager : IDocumentManager<TDocument>
  36.     {
  37.         public static void Start(TDocumentManager dm)
  38.         {
  39.             new Thread(new ProcessDocuments<TDocument, TDocumentManager>(dm).Run).Start();
  40.         }
  41.         protected ProcessDocuments(TDocumentManager dm)
  42.         {
  43.             //注意不能把null赋予泛型类型,因为泛型类型也可以是值类型。
  44.             //其中T doc = default(T);//则会将null赋予引用类型,把0赋予值类型。
  45.             documentManager = dm;
  46.         }
  47.         //使用泛型类型定义成员字段
  48.         private TDocumentManager documentManager;
  49.         protected void Run()
  50.         {
  51.             while (true)
  52.             {
  53.                 if (documentManager.IsDocumentAvailable)
  54.                 {
  55.                     TDocument doc = documentManager.GetDocument();
  56.                     Console.WriteLine("Processing document {0}", doc.Title);
  57.                 }
  58.                 Thread.Sleep(20);
  59.             }
  60.         }
  61.     }
  62.     /// <summary>
  63.     /// 定制泛型接口
  64.     /// </summary>
  65.     public interface IDocumentManager<T>
  66.     {
  67.         void AddDocument(T doc);
  68.         T GetDocument();
  69.         bool IsDocumentAvailable
  70.         {
  71.             get;
  72.         }
  73.     }
  74.     /// <summary>
  75.     /// 定制泛型类
  76.     /// </summary>
  77.     public class DocumentManager<T> : IDocumentManager<T>
  78.     {
  79.         private Queue<T> documentQueue = new Queue<T>();
  80.         //泛型类型作为参数类型
  81.         public void AddDocument(T doc)
  82.         {
  83.             lock (this)
  84.             {
  85.                 documentQueue.Enqueue(doc);
  86.             }
  87.         }
  88.         //泛型类型作为返回类型
  89.         public T GetDocument()
  90.         {
  91.             T doc;
  92.             lock (this)
  93.             {
  94.                 doc = documentQueue.Dequeue();
  95.             }
  96.             return doc;
  97.         }
  98.         public bool IsDocumentAvailable
  99.         {
  100.             get { return (documentQueue.Count > 0) ? true : false; }
  101.         }
  102.     }
  103.     class Program
  104.     {
  105.         static void Main(string[] args)
  106.         {
  107.             DocumentManager<Document> dm = new DocumentManager<Document>();
  108.             ProcessDocuments<Document, DocumentManager<Document>>.Start(dm);
  109.             for (int i = 0; i < 1000; i++)
  110.             {
  111.                 Document doc = new Document("title" + i.ToString(), "content");
  112.                 dm.AddDocument(doc);
  113.                 Console.WriteLine("added document {0}", doc.Title);
  114.                 Thread.Sleep(10);
  115.             }
  116.         }
  117.     }
  118. }

转载于:https://www.cnblogs.com/swollaws/archive/2009/05/12/1455115.html

泛型--定制泛型接口、泛型类--介绍篇相关推荐

  1. 泛型--泛型方法、委托--介绍篇

    一.简单知识和演示 public void page_load(object sender, EventArgs e) {     //把泛型类型赋予方法调用     int x = 4;     i ...

  2. java:泛型(自定义泛型类、自定义泛型接口、泛型的继承和通配符说明)

    目录 一.泛型的介绍 二.泛型的语法 2.1 泛型的声明 2.2 泛型的实例化 2.3 泛型使用举例 2.3 泛型使用的注意事项和细节 2.4 泛型课堂练习题 2.5 自定义泛型类 2.6 自定义泛型 ...

  3. 最牛逼android上的图表库MpChart(一) 介绍篇

    最牛逼android上的图表库MpChart一 介绍篇 MpChart优点 MpChart是什么 MpChart支持哪些图表 MpChart效果如何 最牛逼android上的图表库MpChart(一) ...

  4. Moebius实现Sqlserver集群~介绍篇

    今年是一个不平凡的一年,接触到了很多新艳的,让人兴奋的东西,虽然自己的牙掉了两颗,但感觉自己又年青了两岁,哈哈!进入正题,今年公司开始启用数据库集群,对于Sqlserver来说,实现方式并不是很多,一 ...

  5. 当前订单不支持只花呗支付是什么意思_1、(跑腿介绍篇)支付宝花呗分期线下推广...

    这篇文章主要讲第1篇<花呗分期跑腿介绍篇> 我会以问答的形式,来为大家介绍花呗分期这个业务. 一.花呗分期是什么? 花呗分期是支付宝官方推出的,为了重点宣传花呗分期线下用户去使用开展的活动 ...

  6. Kubernetes系列之Helm介绍篇

    本次系列使用的所需部署包版本都使用的目前最新的或最新稳定版,安装包地址请到公众号内回复[K8s实战]获取 介绍 Helm 是 Deis 开发的一个用于 Kubernetes 应用的包管理工具,主要用来 ...

  7. MonoRail学习-介绍篇(一)

    MonoRail学习-介绍篇 刚刚结束了使用Castle MonoRail的一个项目,所以想将在项目中的一些片段大家一起共享一样.由于这是一个网站项目,所以使用Monorail,因为他使用MVC模式, ...

  8. JEECG Excel 介绍篇

    Excel 介绍篇 AutoPOI 模块可以提供Excel导入导出(支持单表,一对多模型),支持2003和2007的模板,同时支持使用模板的导出 excel导出的的学习成本降低非常低,一般的报表也可以 ...

  9. 负载均衡原理剖析与实践:负载均衡第一篇-介绍篇

    负载均衡第一篇-介绍篇   系列文章索引: 负载均衡第一篇-介绍篇 负载均衡第二篇-负载均衡基础知识普及   前言:相信朋友们对负载均衡应该不陌生了!特别是对搞运维的朋友!可能很多的技术人员认为,负载 ...

最新文章

  1. Git使用教程-命令总结大全
  2. mysql-in关键字,分组查询,分页查询
  3. mysql jar jdk1.6_搭建非安装版mysql+jdk1.6+tomcat6
  4. 浏览器兼容性问题-JSDOM(转)
  5. mysql 组复制 不一致_MySQL主从复制什么原因会造成不一致,如何预防及解决
  6. PPC丢失后,手机信息如何保护?(C#)
  7. do...while(); 语句在宏定义中的应用。
  8. 用 js 写的 WebSocketHeartBeat,心跳检测
  9. JanusGraph批量导入数据优化
  10. 初步熟悉RHEL 8
  11. QCC3007-button篇 使用ADK Configuration Tool配置按键
  12. labview利用USB-6341数据采集卡采集发动机传感器信号(总结篇)
  13. 【Transformer论文模型细致讲解】
  14. 分布式 | dble元数据更新同步
  15. [SystemC]SystemC中的模块和程序
  16. ApacheCon Asia 2022 开启报名:Pulsar 技术议题重磅亮相
  17. 股票开户天宇优配|新冠药概念走势活跃,九安医疗涨停,森萱医药
  18. 华为诺亚方舟实验室简述
  19. 虚拟机 安装 CUDA 可行性说明
  20. 西门子200SMART(十)写程序的思路

热门文章

  1. mysql使用Navicat创建分区
  2. 详解计算机内部存储数据的形式 二进制数
  3. Tomcat和Resin有什么区别,工作中你怎么选择?
  4. Oracle ASM Cluster File Systems (ACFS)应用指南
  5. [考试反思]0819NOIP模拟测试26:荒芜
  6. Html Dom 的nodetype解析 转自“sweting”
  7. thinkphp的使用——隐藏index.php
  8. 搭建git服务器(权限管理)
  9. (连通图 模板题 无向图求桥)Critical Links -- UVA -- 796
  10. CodeProject 工具收藏