泛型--定制泛型接口、泛型类(转载)

简介:
 

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

约束

说明

T:结构

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

T:类

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

T:new()

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

T:<基类名>

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

T:<接口名称>

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

T:U

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

      简单约束说明实例:
ContractedBlock.gif ExpandedBlockStart.gif Code
    //值类型struct|引用类型class约束
    public struct Text
    {
 
    }
 
    
public class Test<T>
        
where T : struct
    {
        
//T在这里是一个值类型
    }
 
    
public class Check
    {
        Test
<Text> test = new Test<Text>();
    }
 
    
//new()约束
    public class Text
    {
        
public Text() { }//无参数的构造函数
    }
 
    
public class Test<T>
        
where T : new()
    {
        
//可以在其中使用T t = new T();
    }
 
    
public class Check
    {
        Test
<Text> test = new Test<Text>();
    }
 
    
//基类约束
    public class Text 
    {
        
public void Add() { }
    }
 
    
public class Test<T>
        
where T : Text//T继承至Text
    {
        
//可以在类型为T的变量上调用Add()方法
    }
 
    
//接口约束见下面实例 
       自定义泛型实例:
ContractedBlock.gif ExpandedBlockStart.gif Code

namespace Wrox.ProCSharp.Generics
{
    
using System;
    
using System.Threading;
    
using System.Collections.Generic;
 
    
public interface IDocument
    {
        
string Title { get;}
        
string Content { get;}
    }
 
    
public class Document : IDocument
    {
        
private string title;
        
public string Title
        {
            
get { return title; }
        }
 
        
private string content;
        
public string Content
        {
            
get { return content; }
        }
 
        
public Document(string title, string content)
        {
            
this.title = title;
            
this.content = content;
        }
    }
 
    
/// <summary>
    
/// 定制泛型类【使用接口约束】
    
/// </summary>
    public class ProcessDocuments<TDocument, TDocumentManager>
        
where TDocument : IDocument
        
where TDocumentManager : IDocumentManager<TDocument>
    {
        
public static void Start(TDocumentManager dm)
        {
            
new Thread(new ProcessDocuments<TDocument, TDocumentManager>(dm).Run).Start();
        }
 
        
protected ProcessDocuments(TDocumentManager dm)
        {
            
//注意不能把null赋予泛型类型,因为泛型类型也可以是值类型。
            
//其中T doc = default(T);//则会将null赋予引用类型,把0赋予值类型。
            documentManager = dm;
        }
 
        
//使用泛型类型定义成员字段
        private TDocumentManager documentManager;
 
        
protected void Run()
        {
            
while (true)
            {
                
if (documentManager.IsDocumentAvailable)
                {
                    TDocument doc 
= documentManager.GetDocument();
                    Console.WriteLine(
"Processing document {0}", doc.Title);
                }
                Thread.Sleep(
20);
            }
        }
    }
 
    
/// <summary>
    
/// 定制泛型接口
    
/// </summary>
    public interface IDocumentManager<T>
    {
        
void AddDocument(T doc);
        T GetDocument();
        
bool IsDocumentAvailable
        {
            
get;
        }
    }
 
    
/// <summary>
    
/// 定制泛型类
    
/// </summary>
    public class DocumentManager<T> : IDocumentManager<T>
    {
        
private Queue<T> documentQueue = new Queue<T>();
 
        
//泛型类型作为参数类型
        public void AddDocument(T doc)
        {
            
lock (this)
            {
                documentQueue.Enqueue(doc);
            }
        }
 
        
//泛型类型作为返回类型
        public T GetDocument()
        {
            T doc;
            
lock (this)
            {
                doc 
= documentQueue.Dequeue();
            }
            
return doc;
        }
 
        
public bool IsDocumentAvailable
        {
            
get { return (documentQueue.Count > 0? true : false; }
        }
    }
 
    
class Program
    {
        
static void Main(string[] args)
        {
            DocumentManager
<Document> dm = new DocumentManager<Document>();
 
            ProcessDocuments
<Document, DocumentManager<Document>>.Start(dm);
 
            
for (int i = 0; i < 1000; i++)
            {
                Document doc 
= new Document("title" + i.ToString(), "content");
                dm.AddDocument(doc);
                Console.WriteLine(
"added document {0}", doc.Title);
                Thread.Sleep(
10);
            }
        }
    }
}

 原文地址:http://www.cnblogs.com/swollaws/archive/2009/05/12/1455115.html

版权说明

  如果标题未标有<转载、转>等字则属于作者原创,欢迎转载,其版权归作者和博客园共有。
  作      者:温景良
  文章出处:http://wenjl520.cnblogs.com/  或  http://www.cnblogs.com/

posted @ 2009-05-12 23:27 温景良(Jason) Views( 203) Comments( 0) Edit 收藏
 

公告

hidden hit counter
 
本文转自 我的程序人生博客园博客,原文链接: http://www.cnblogs.com/wenjl520/archive/2009/05/12/1455284.html,如需转载请自行联系原作者
 
相关文章
|
5月前
|
存储 算法 编译器
泛型的讲解
泛型的讲解
40 0
|
8月前
|
Java
java泛型:泛型类,泛型接口,泛型方法,泛型集合
java泛型:泛型类,泛型接口,泛型方法,泛型集合
|
9月前
|
编译器 C#
C# 泛型
C# 泛型
39 0
|
安全 Java 编译器
泛型的使用
今天和考上研究生的老同学聊了一会,知晓他在重新学习Java,并且学到了泛型这个地方,所以今天来总结一下泛型这个地方。
|
Java
Java泛型02:自定义泛型类、泛型方法
Java泛型02:自定义泛型类、泛型方法
440 0
|
Java 编译器 API
泛型-详解
泛型-详解
97 0
泛型-详解
|
安全 JavaScript Java
泛型中的 T、E、K、V、?等等,究竟是啥?
泛型中的 T、E、K、V、?等等,究竟是啥?
泛型中的 T、E、K、V、?等等,究竟是啥?
|
Java 编译器 安全
关于泛型,你可能不知道的事儿
型没有其看起来那么深不可测,它并不神秘与神奇。泛型是 Java 中一个很小巧的概念,但同时也是一个很容易让人迷惑的知识点,它让人迷惑的地方在于它的许多表现有点违反直觉。
1574 0
|
安全 Java 编译器
java基础巩固-详解泛型
java泛型(generics)为jdk5引入的新特性,泛型提供了编译时类型安全检测机制,可以在编译时检测到非法的类型。 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
1355 0