Framework类库中的泛型

泛型可以使代码重用,提高开发效率

CLR允许在引用类型、值类型或接口中定义泛型方法;

CLR允许创建泛型引用类型、泛型值类型(枚举不允许创建)、泛型委托类型和泛型接口类型;

System.Collections.Generics中定义了List<T>,<T>表示它操作的是一个未指定数据类型;定义泛型类型或方法时,T是一个变量名,在源代码中能够使用一个数据类型的任何位置都能用T,例如方法参数、返回值等等。

泛型参数变量要么称为T,要么以T开头(如Tkey,TEvent...)

定义好泛型类型后,使用泛型类型或方法时,制定具体的类型实参

var validationResult = new List<ValidationResult>();

泛型的优势

  • 源代码保护

    使用泛型算法时候,不需要了解算法内部的具体实现
  • 类型安全

    将泛型算法运用于一个具体的类型,只有与数据类型兼容算法的对象才能使用算法,若不兼容,便会编译错误或运行异常
  • 更加清晰的代码

    由于编译器强制类型安全,减少了代码中的转型次数
  • 更佳的性能

    由于装箱会造成性能的浪费,通过泛型避免了装箱

下面是一段泛型与非泛型的算法性能测试对比

    class Program
    {
        static void Main(string[] args)
        {
            ValueTypePreTest();
            ReferenceTypePreTest();
            Console.ReadKey();
        }

        private static void ValueTypePreTest()
        {
            const int count = 10000000;
            using (new OperationTimer("List<Int32>"))
            {
                List<int> l = new List<int>();
                for (int i = 0; i < count; i++)
                {
                    l.Add(i);
                    int x = l[i];
                }
                l = null;//确保进行垃圾回收
            }

            using (new OperationTimer("ArraryList of Int32"))
            {
                ArrayList arr = new ArrayList();
                for (int i = 0; i < count; i++)
                {
                    arr.Add(i);
                    int x = (int)arr[i];
                }
                arr = null;
            }
        }

        private static void ReferenceTypePreTest()
        {
            const int count = 10000000;
            using (new OperationTimer("List<String>"))
            {
                List<string> l = new List<string>();
                for (int i = 0; i < count; i++)
                {
                    l.Add("X");
                    string x = l[i];
                }
                l = null;//确保进行垃圾回收
            }

            using (new OperationTimer("ArraryList of String"))
            {
                ArrayList arr = new ArrayList();
                for (int i = 0; i < count; i++)
                {
                    arr.Add("X");
                    string x = (string)arr[i];
                }
                arr = null;
            }
        }

    }

    class OperationTimer : IDisposable
    {
        private long _start;
        private string _text;
        private int _collectionCount;

        public OperationTimer(string text)
        {
            _text = text;
            _collectionCount = GC.CollectionCount(0);
            _start = Stopwatch.GetTimestamp();
        }

        public static void PreparForPeration()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }

        public void Dispose()
        {
            Console.WriteLine("{0,6:###.00} seconds(GCs={1,3}) {2}",
                (Stopwatch.GetTimestamp() - _start) / (double)Stopwatch.Frequency,
                GC.CollectionCount(0) - _collectionCount,
                _text
                );
        }
    }

Wintellect的Power Collections库

Wintellect公司开发的一些C++集合类库

http://www.wintellect.com/dotnet-software-development

泛型基础结构

开放类型和封闭类型

具有泛型类型参数的类型称为开放类型(例如:Directory<,>),CLR禁止构造开放类型的任何实例

代码引用一个泛型类型时,可指定一组泛型类型实参,假如为所有类型实参传递都是实际数据类型,称为封闭类型(例如:List<string>

开放类型和封闭类型

具有泛型类型参数的类型称为开放类型(例如:Directory<,>),CLR禁止构造开放类型的任何实例

代码引用一个泛型类型时,可指定一组泛型类型实参,假如为所有类型实参传递都是实际数据类型,称为封闭类型(例如:List<string>

泛型类型和继承

泛型类型任然是一种类型,它可以从其他类型派生。

泛型类型的同一性

不要为了简化代码而定义一个新的类型继承泛型,这样会散失同一性和相等性,可以通过下面的方式简化代码输入

using DateTimeList=System.Collections.Generic.List<DateTime>;

代码爆炸

CLR 优化了泛型类型的编译代码,避免了每次都要为不同的泛型类型生成对应的代码

泛型接口

通过泛型接口避免值类型发生装箱

   public interface IEnumerator<T>:IDisposable,IEnumerator
   {
       T Current{get;}
   }

泛型委托

保证任何类型的对象都能以一种类型安全的方式传给回调方法;而且泛型委托也是为了避免一个值类型实例在传递给回调方法时不再发生装箱

委托和接口的协变和逆变泛型类型实参

http://www.cnblogs.com/liunlls/p/inout.html

泛型方法

泛型除了可以定义类型的参数,还可以为方法定义一个只作用域于方法的类型参数

泛型的类型推断

        public static void Display<T>(T input){
            System.Console.WriteLine(input);
        }
        Display(123);
        Display("aaa")

泛型和其他成员

在C#中,属性、事件、索引器、构造函数等成员是不能有类型参数的,但是在泛型类型中,这些成员的代码是可以使用类型参数的;

C#不允许他们指定自己的泛型类型参数,C#团队认为开发人员很少需要将这些成员作为泛型使用,当然为这些成员添加泛型代价也很高

可验证性和约束

http://www.cnblogs.com/liunlls/p/Generics.html

最新文章

  1. asp.net core 简单部署
  2. Python学习路程day18
  3. 编译.NET项目的时候报错错误“ResGen.exe”已退出,代码为 -1073741701
  4. Python之禅+八荣八耻
  5. 介绍kali下的一些小工具
  6. mac下java 开发环境搭建
  7. Scene视图辅助线绘制
  8. [30分钟]MSSQL快速入门教程
  9. Hibernate与IBatis的优缺点及可行性分析
  10. 搭建typescript开发环境最详细的全过程
  11. (转)sizeof
  12. jquery-1.11.1.js
  13. 吐血bug-- 多个input框接连blur事件导致alert接连弹出
  14. Python基础之迭代器和生成器
  15. Git branch &amp;&amp; Git checkout常见用法
  16. Nginx 反向代理 -- 一路上的坑
  17. CSDN博客文章的备份及导出电子书CHM
  18. Tomcat部署Web应用
  19. make的自动变量和预定义变量
  20. 【HTML5游戏开发】简单的《找不同汉字版》,来考考你的眼力吧

热门文章

  1. Android内存泄漏分享
  2. HTML和CSS经典布局6
  3. ASP.NET MVC SSO单点登录设计与实现
  4. Express4 启航指南
  5. How.To.Process.Image.Infomation.Of.Rotate.And.Flip.From.Server
  6. Git命令汇总
  7. PHP运行及语句及逻辑
  8. C++ 回调函数 实现 的测试代码
  9. rabbitMQ第五篇:Spring集成RabbitMQ
  10. 打造自己的html5视频播放器