• C#泛型泛型类


    为什么需要泛型:

    CLR 2.0的一个新特性是泛型。在.CLR 1.0 中,要创建一个灵活的类或方法,但该类或方法在编译期间不知道使用什么类,就必须以 Object 类为基础。而 Object 类在编译期间没有类型安全性,因此必须进行强制类型转换。另外,给值类型使用Object类会有性能损失。

    性能 

    第一、泛型的一个主要优点是性能.避免装箱,拆箱

       例如:ArrayList方法Add(Value),value值只要继承object均可以添加进去,但是需要:装箱 ;foreach时需要拆箱

      (从值类型转换为引用类型称为装箱反之称拆箱)

    第二、类型安全

      例如:List<T>中,泛型类型 T若 定义了允许使用的类型int,那么Add(value)方法中value只允许int值类型

    第三、二进制代码重用(泛型类可以定义一次,用许多不同的类型实例化)

      例如:List<int> list = new List<int>(); list.Add(1); 

                  List<string> stringList = new List<string>(); stringList.Add("string");

      泛型类型可以在一种语言中定义,在另一种.NET语言中使用。 

    案例:

    DocumentManager

    /*
     * 说明:使用泛型文档管理器的示例 
     * 
     * 注意: 
     * default关键字根据上下文可以有多种含义。switch语句使用 default定义默认情况。在泛型中,根
     * 据泛型类型是引用类型还是值类型,default关键字用于将泛型类型初始化为 null或 0。 
     *
     * 创建:2012-04-26
     */
    using System;
    using System.Collections.Generic; 
    using System.Text;
    using System.Collections;
    
    namespace DocumentManager
    {
        //类约束指定,类型 T必须执行接口IDocument
        public class DocumentManager<T> where T :IDocument
        {
    
            private readonly Queue<T> documentQueue = new Queue<T>();
            /// <summary>
            /// AddDocument()方法将一个文档添加到
            /// 队列中。如果队列不为空,IsDocumentAvailable只读属性就返回 true
            /// </summary>
            /// <param name="doc"></param>
            public void AddDocument(T doc)
            {
                lock (this)
                {
                    documentQueue.Enqueue(doc);
                }
            }
            /// <summary>
            /// 队列中有值返回True否则False
            /// </summary>
            public bool IsDocumentAvailable
            {
                get { return documentQueue.Count > 0; }
            }
            /// <summary>
            /// 给类型 T指定默认值 
            /// </summary>
            /// <returns></returns>
            public T GetDocument()
            {
                T doc = default(T); //泛型默认值:使用 default 关键字
                lock (this)
                {
                    doc = documentQueue.Dequeue();
                }
                return doc;
            }
            /// <summary>
            /// 展示所有文档
            /// </summary>
            public void DisplayAllDocument()
            {
                foreach (T doc in documentQueue)
                {
                    Console.WriteLine(((IDocument)doc).Title);
                } 
            }  
        }
    }

    Document

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DocumentManager
    {
        public class Document : IDocument
        {
            public Document() 
            {
    
            }
            public string Title { get; set; }
            public string Content { get; set; }
            public Document(string title, string content)
            {
                this.Title = title;
                this.Content = content;
            }
        }
    }

    TDocument

    namespace DocumentManager
    {
        public class TDocument : IDocument
        {
            public TDocument() 
            {
    
            }
            public string Title { get; set; }
            public string Content { get; set; }
            public TDocument(string title, string content)
            {
                this.Title = title;
                this.Content = content;
            }
        }
    }
    /*
     * 如果泛型类需要调用泛型类型上的方法,就必须添加约束 
     * 
     */
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DocumentManager
    {
        public interface IDocument
        {
            string Title { get; set; }
            string Content { get; set; }
        }
    }

    Program

     class Program
        {
            static void Main(string[] args)
            {
                //DocumentManager<TDocument> tm = new DocumentManager<TDocument>();
                //tm.AddDocument(new TDocument("Title TDocument","Content TDocument"));
                //tm.DisplayAllDocument();
    
                DocumentManager<Document> dm = new DocumentManager<Document>();
                dm.AddDocument(new Document("Title A", "Sample A")); 
                dm.DisplayAllDocument();
    
                dm.AddDocument(new Document("Title B", "Sample B"));
                dm.DisplayAllDocument();
                if (dm.IsDocumentAvailable)
                {
                    Document d = dm.GetDocument();
                    Console.WriteLine(d.Content);
                }
            }
        }

    结果:建议先自己心算下……

    (是不是和你的意愿不一致?那再好好看看代码)

    注意:

     
    default关键字根据上下文可以有多种含义。switch语句使用 default定义默认情况。在泛型中,根
    据泛型类型是引用类型还是值类型,default关键字用于将泛型类型初始化为 null或 0。

    如果泛型类需要调用泛型类型上的方法,就必须添加约束 。格式: where+约束类型

     

    约    束  说    明 
    where T : struct  使用结构约束,类型 T必须是值类型 
    where T : class  类约束指定,类型 T必须是引用类型 
    where T : IFoo  指定类型T必须执行接口 IFoo
    where T : Foo  指定类型T必须派生于基类 Foo
    where T : new()  这是一个构造函数约束,指定类型 T必须有一个默认构造函数 
    where T : U 

    这个约束也可以指定,类型 T1 派生于泛型类型 T2。该约束也称为裸类型约

    在where子句中,只能定义基类、接口和默认构造函数。

     

    静态成员 

    泛型类的静态成员需要特别关注。泛型类的静态成员只能在类的一个实例中共享
                 //泛型类的静态成员需要特别关注。泛型类的静态成员只能在类的一个实例中共享
                //由于对一个string类型和一个int类型使用了 StaticDemo<T>类,所以存在两组静态字段:
                StaticDemo<int>.x = 1;
                StaticDemo<string>.x = 11;
                StaticDemo<char>.x = 111;
                Console.WriteLine(StaticDemo<string>.x);
                Console.WriteLine(StaticDemo<int>.x);
        public class StaticDemo<T>
        {
            public static int x;
        }

                                                                                                                                                             引自《C#高级编程》


    作者:PEPE
    出处:http://pepe.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    WCF系列(五) 也谈序列化(下)
    优秀程序员的十个习惯
    WCF系列(九) WCF安全系列(四) WSHttpBinding绑定之Transport安全模式
    TCP/IP 协议简单分析
    技巧:在Silverlight应用程序中进行数据验证
    WCF系列(三) WCF配置文件注释
    [转]ASP.NET(C#)常用代码30例
    服务器端 在iframe中控制父窗体div并调用父窗体Button
    GridView的模版列中加入按钮,触发按钮事件后,如何获取该行的某个值?
    通用分页 模块
  • 原文地址:https://www.cnblogs.com/PEPE/p/2471568.html
Copyright © 2020-2023  润新知