【CSharp】泛型

using System;
using System.Collections.Generic;

namespace Wrox.ProCSharp.Generics
{
    public class DocumentManager where TDocument : IDocument
    {
        private readonly Queue documentQueue = new Queue();

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

        public bool IsDocumentAvailable => documentQueue.Count > 0;


        public void DisplayAllDocuments()
        {
            foreach (TDocument doc in documentQueue)
            {
                Console.WriteLine(doc.Title);
            }
        }


        public TDocument GetDocument()
        {
            TDocument doc = default(TDocument);
            lock (this)
            {
                doc = documentQueue.Dequeue();
            }
            return doc;
        }
    }

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

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

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

        public string Title { get; set; }
        public string Content { get; set; }
    }
}

默认值

泛型类DocumentManager中有个GetDocument()方法。在这个方法中,应该用null初始化TDocument类型的局部变量。但是 ,不能把null赋予泛型类型。原因是泛型类型也可以实例化为值类型,而null只能用于引用类型。通过 default关键字,将null赋予引用类型,将0赋予值类型。

约束

如果泛型类需要 调用泛型类型中的方法,就必须添加约束。

对于DocumentManager,文档的所有标题应在DisplayAllDocuments()方法中显示。Document类实现带有Title和Content属性的IDcoment接口。

要使用DocumentManager类显示文档,可以将类型TDocument强制转换为IDocument接口,以显示标题。

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

最好给DocumentManager类定义一个约束:TDocument类型必须实现IDocument接口。为了在泛型类型的名称中指定该要求,使用where子句指定实现IDcument接口的要求。

泛型支持的约束类型
约束 说明
where T :struct 接口 约束,类型T必须为值类型
where T :class 类约束,类型T必须为引用约束
where T :IFoo 类型T必须实现IFoo接口
where T :Foo 类型T必须派生自基类Foo
where T :new() 构造函数约束,指定类型T必须有一个默认构造函数。且只能为默认构造函数定义构造函数约束,不能为其他构造函数定义构造函数约束
where T :T2 类型T派生自泛型类型T2

静态成员

泛型类的静态成员只能在泛型类的一个实例中共享。

class Program
{
    public static void Main(string[] args)
    {
        StaticDemo.x = 1;
        StaticDemo.x = 2;
        StaticDemo.x = 2;
        StaticDemo.x = 1;
        StaticDemo.x = 1;
        StaticDemo.x = 2;
        
        Console.WriteLine(StaticDemo.x);    // 2
        Console.WriteLine(StaticDemo.x); // 1
        Console.WriteLine(StaticDemo.x); // 2
        
        Console.ReadKey();
    }
}

class StaticDemo
{
    public static int x;
}

 

你可能感兴趣的:(CSharp)