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

 

      泛型类的定义类似于一般的类,只是要使用泛型类型声明。之后就可以在类中把泛型类型用作成员字段,或方法的参数类型。在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。这些限制称为约束。约束是使用 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,如需转载请自行联系原作者
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值