泛型类功能

1.创建一个泛型类

 public class DocumentMangereList<T>
    {
        private readonly Queue<T> documentQueue = new Queue<T>();

        public void AddDocument(T doc)
        {
            lock (this)
            {
                documentQueue.Enqueue(doc);
            }
        }

        public bool IsDocumentAvailable
        {
            get { return documentQueue.Count > 0; }
        }
  }

 

2.默认值

现在DocumentMangereList<T>类添加一个GetDocument()方法。 在这个方法中,应把类型T指定为null。 但是,不能把null赋予泛型类型。原因是泛型类型也可以实例化为值类型,而 null 只能用于引用类型。为了解决这个问题,可以使用 default 关键字。通过 default关键字,将 null赋予引用类型,将 赋予值类型。

//默认值
public T GetDocument()
{
    T doc = default(T);
    lock (this)
    {
        doc = documentQueue.Dequeue();
    }
    return doc;
}


3.约束

如果泛型类需要调用泛型类型中的方法,就必须添加约束。对于DocumentManagerList,文档的所有标题应在 DisplayAllDocuments()方法中显示。Document类实现带有 Title 和 Content属性的 IDocment接口:

public interface IDocument
{
    string Title { get; set; }

    string Content { get; set; }
}

public class Document : IDocument
{
    public Document() { }

    public Document(string title, string content)
    {
        this.Title = title;
        this.Content = content;
    }

    public string Title { get; set; }

    public string Content { get; set; }
}

 

要使用 DocumentManagerList<T> 类显示文档,可以将类型 强制转换为 IDocument接口,以显示标题:

//显示文档
public void DisplayAllDocuments()
{
    foreach (T doc in documentQueue)
    {
        Console.WriteLine(((IDocument)doc).Title);
    }
}


问题是,如果类型T没有实现IDocument接口,这个类型强制转换就会导致一个运行异常。最

好给DocumentManagerList<TDocument> 类定义一个约束:TDocument类型必须实现IDocunent接口。为了在泛型类型的名称中指定该要求,将 T改为TDocument。 where指定了实现IDocment接口的要求:

public class DocumentMangereList<T> where T:IDocument
{
    //显示文档
    public void DisplayAllDocuments()
    {
        foreach (T doc in documentQueue)
        {
            Console.WriteLine(doc.Title);
        }
  }
  
  //...
}

 

Main()方法中,用 Docunent类型实例化DocomentManageList<T>,Document类型实现了

需要的IDocument接 口。接着添加和显示新文档,检索其中一个文档:

static void Main(string[] args)
{
    var dm = new DocumentMangereList<Document>();
    dm.AddDocument(new Document("Title A", "Sanple A"));
    dm.AddDocument(new Document("Title B", "Sanple B"));

    dm.DisplayAllDocuments();

    if (dm.IsDocumentAvailable)
    {
        Document d = dm.GetDocument();
        Console.WriteLine(d.Content);
    }
}

 

输出:

 

泛型支持几种约束类型

使用泛型类型还可以合并多个约束。where TIFoo,new() 约束和 MyClass<T> 声明指定,类型 必须实现 IFoo 接口,且必须有一个默认构造函数。

public class MyClass<T> where T: IFoo ,new()

{

    //...

}

4.继承

public abstract class Calc<T>
{
    public abstract T Add(T x, T y);
    public abstract T Sub(T x, T y);
}

public class IntCalc:Calc<int>
{
    public override int Add(int x, int y)
    {
        return x + y;
    }

    public override int Sub(int x, int y)
    {
        return x - y;
    }
}

 

5.静态成员

泛型类的静态成员需要特别关注。泛型类的静态成员只能在类的一个实例中共享。下面看一个例子,其中 StaticDemo 包含静态字段x:

public class StaticDemo<T>
{
    public static int x;
}

 

由于同时对一个string 类型和一个 int 类型使用了 StaticDemo<T> 类,所以存在两组静态字段:

class Program
{
    static void Main(string[] args)
    {
        StaticDemo<string>.x = 4;
        StaticDemo<int>.x = 5;
        Console.WriteLine(StaticDemo<string>.x);//输出 4
    }
}

 

posted @ 2013-08-23 19:30  罗马景行  阅读(258)  评论(0编辑  收藏  举报