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


    泛型是由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);
    小结:泛型内容比较多,只是讲了一些比较基本的内容。
  • 相关阅读:
    Python3 list基本操作
    Oracle Sql关于case-when,if-then,decode
    Oracle12c解锁scott测试用户
    Java得到下一天日期
    SQLiteTest源代码
    实况照片的视频合并
    一个支持中文的日志类
    为对话框添加背景图片
    获取当前应用程序的文件名
    Win7系统x64正在准备再循环
  • 原文地址:https://www.cnblogs.com/ylwn817/p/2065265.html
Copyright © 2020-2023  润新知