博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C#语言学习之旅(8)--泛型

Posted on 2013-01-09 11:56  米粒3  阅读(161)  评论(0编辑  收藏  举报

泛型是由2.0引进来的,有了泛型,就不再使用object类了。泛型相当于c++中的模板,泛型是C#语言的一个结构而且是CLR定义的。泛型的最大优点就是提高了性能,减少了值类型和引用类型的拆箱和装箱。

8.1 创建泛型类

 创建泛型类和定义一般类类似,只是要使用泛型类型声明。下面给出例子:

泛型简单demo
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace GenericDemo
{
    
//泛型
    public class LinkedListNode<T>
    {
        
public LinkedListNode(T value)
        {
            
this.value = value;
        }

        
private T value;
        
public T Value
        {
            
get { return value; }
        }

        
private LinkedListNode<T> next;
        
public LinkedListNode<T> Next
        {
            
get { return next; }
            
internal set { next = value; }
        }

        
private LinkedListNode<T> prev;
        
public LinkedListNode<T> Prev
        {
            
get { return prev; }
            
internal set { prev = value; }
        }

    }

    
public class LinkedList<T> : IEnumerable<T>
    {
        
private LinkedListNode<T> first;

        
public LinkedListNode<T> First
        {
            
get { return first; }
        }

        
private LinkedListNode<T> last;

        
public LinkedListNode<T> Last
        {
            
get { return last; }
        }

        
//添加
        public LinkedListNode<T> AddLast(T node)
        {
            LinkedListNode
<T> newNode = new LinkedListNode<T>(node);
            
if (first == null)
            {
                first 
= newNode;
                last 
= first;
            }
            
else
            {
                last.Next 
= newNode;
                last 
= newNode;
            }
            
return newNode;
        }



        
#region IEnumerable<T> Members

        
public IEnumerator<T> GetEnumerator()
        {
            LinkedListNode
<T> current = first;

            
while (current != null)
            {
                
yield return current.Value;
                current 
= current.Next;
            }
        }

        
#endregion

        
#region IEnumerable Members

        
//返回枚举值
        IEnumerator IEnumerable.GetEnumerator()
        {
            
return GetEnumerator();

        }

        
#endregion
    }
    
class Program
    {
        
static void Main(string[] args)
        {
            
//所使用泛型
            LinkedList<int> list2 = new LinkedList<int>();
            list2.AddLast(
3);
            list2.AddLast(
5);
            list2.AddLast(
7);

            
foreach (int i in list2)
            {
                Console.WriteLine(i);
            }

        }
    }
}

8.2 泛型类的特性

a.默认值

通过使用default关键字,能够将null赋予引用类型,将0赋予值类型

b.约束

如果泛型类调用泛型类型上的方法,就必须添加约束下面给出一个例子来讲解。

约束demo
    //接口
    public interface IDocument
    {
        
string Title { getset; }
        
string Content { getset; }
    }
 
//使用约束
    public interface IDocumentManager<TDocument>
     
where TDocument : IDocument
    {
        
void AddDocument(TDocument doc);
        TDocument GetDocument();
        
bool IsDocumentAvailable { get; }
    }
   
public class Document : IDocument
    {
        
public Document()
        {

        }

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


        
public string Title {getset;}


        
public string Content {getset;}

    }
   
public class DocumentManager<TDocument> : IDocumentManager<TDocument>
        
where TDocument: Document
    {
        
private readonly Queue<TDocument> documentQueue = new Queue<TDocument>();

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

        
public TDocument GetDocument()
        {
            TDocument doc 
= default(TDocument);

            
lock (this)
            {
                doc 
= documentQueue.Dequeue();
            }

            
return doc;
        }

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

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

   
class Program
    {
        
static void Main(string[] args)
        {
            DocumentManager
<Document> dm = new DocumentManager<Document>();
            dm.AddDocument(
new Document("Title A""Sample A"));
            dm.AddDocument(
new Document("Title B""Sample B"));

            dm.DisplayAllDocuments();

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

            dm.DisplayAllDocuments();
            
        }
    }

 说明:对于上面代码中的DocumentManager<T>,文档的标题应在DisplayAllDocuments方法显示。要是这个方法显示文档,可以将类型T强制转换为IDocument接口,来显示标题。如下代码:

复制代码
  public void DisplayAllDocuments()
        {
            
foreach (T doc in documentQueue)
            {
                Console.WriteLine(((IDocument)doc).Title);
            }
        }
复制代码

 当类型T没有执行IDocument接口,这个类型转换将会生成一个运行异常。如何解决这个问题呢,这个时候使用约束就可以了,就是给DocumentManager<TDocument>类定义一个约束:让TDocument类型必须执行IDocument接口,可以使用where子句指定了执行Idocument接口的要求。如下代码:

 public class DocumentManager<TDocument> : IDocumentManager<TDocument>
        
where TDocument: Document

 这样就可以编写了,让类型T包含属性title啦,如下代码:

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

 c.继承

泛型类型可以执行泛型接口,也可以派生于一个类。

下面给出一个例子来:

泛型继承demo
    public abstract class Calc<T>
    {
        
public abstract T Add(T x, T y);
        
public abstract T Sub(T x, T y);
    }

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

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

 d.静态成员

泛型中的静态成员只能在类得一个实例化中共享,下面看一个例子

静态成员demo
 public class StaticDemo<T>
    {
        
public static int x;
    }
   StaticDemo
<string>.x = 4;
            StaticDemo
<int>.x = 5;
            Console.WriteLine(StaticDemo
<string>.x);
小结:泛型内容比较多,只是讲了一些比较基本的内容。