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

泛型(Generics)的更多相关文章

  1. [19/03/23-星期六] 容器_ 泛型Generics

    一.概念 生活中的容器不难理解,是用来容纳物体的,程序中的“容器”也有类似的功能,就是用来容纳和管理数据. 数组就是一种容器,可以在其中放置对象或基本类型数据. ---优势:是一种简单的线性序列,可以 ...

  2. Java 泛型(Generics)

    Generics, 类似C++中的模版. 允许在定义类和接口的时候使用类型参数(type parameters), 声明的类型参数在使用的时候用具体的类型来替换. 如 ArrayList<Str ...

  3. Java 泛型(Generics) 综述

    一. 引子 一般的类和方法.仅仅能使用详细类型:要么是基本类型.要么是自己定义类型.假设要编写能够应用于多种类型的代码,这样的刻板的限制对代码的束缚就会非常大. 多态算是一种泛化机制,但对代码的约束还 ...

  4. Welcome-to-Swift-22泛型(Generics)

    泛型代码可以确保你写出灵活的,可重用的函数和定义出任何你所确定好的需求的类型.你可以写出避免重复的代码,并且用一种清晰的,抽象的方式表达出来. 泛型是Swift许多强大特征中的其中一个,许多Swift ...

  5. [JavaCore]JAVA中的泛型

    JAVA中的泛型 [更新总结] 泛型就是定义在类里面的一个类型,这个类型在编写类的时候是不确定的,而在初始化对象时,必须确定该类型:这个类型可以在一个在里定义多个:在一旦使用某种类型,在类方法中,那么 ...

  6. Java1.5泛型指南中文版(Java1.5 Generic Tutorial)

    Java1.5泛型指南中文版(Java1.5 Generic Tutorial) 英文版pdf下载链接:http://java.sun.com/j2se/1.5/pdf/generics-tutori ...

  7. java泛型小问题

    几年前当Java5还未正式发布的时候,看到过一些人写的介绍Tiger中的新特性,当时对我第一感觉冲击最大的就是泛型(generics)和注释(annotation),因为它们直接影响了我们编码的语法习 ...

  8. 泛型-----键值对----映射 hashmap--entry中key value 链表

    connection map 集合框架 * java.util.Collection *集合与数组相似,也是可以保存一组元素,并且提供了操作元素的相关方法. *collection是所有集合的顶级接口 ...

  9. Java下的框架编程(反射,泛型,元数据,CGLib,代码动态生成,AOP,动态语言嵌入)

    Java 虽然没有动态语言般暴起,但仍然天连天,水接水的生出好多框架技术---反射(reflection),泛型(generics),元数据(annotation),proxies(proxy/cgl ...

随机推荐

  1. Java基础系列——IO流

    ---恢复内容开始--- Java对数据的操作都是通过流的方式,数据的输入和输出是相对内存来说的,将外设的数据读到内存:输入流:将内存的数据写到外设:输出流. 流按操作数据分为两种:字节流,字符流. ...

  2. Android应用安全开发之浅谈加密算法的坑

      <Android应用安全开发之浅谈加密算法的坑> 作者:阿里移动安全@伊樵,@舟海 阿里聚安全,一站式解决应用开发安全问题     Android开发中,难免会遇到需要加解密一些数据内 ...

  3. [译]WebForms vs. MVC

    译者介绍 小小.NET学童,滴答…滴答…的雨…… 正文如下======================================================= 原文示例(VS2012): 1 ...

  4. Java NIO1:I/O模型概述

    I/O模型 在开始NIO的学习之前,先对I/O的模型有一个理解,这对NIO的学习是绝对有好处的.我画一张图,简单表示一下数据从外部磁盘向运行中进程的内存区域移动的过程: 这张图片明显忽略了很多细节,只 ...

  5. iOS开发系列--Objective-C之KVC、KVO

    概述 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听( ...

  6. 探索c#之递归APS和CPS

    接上篇探索c#之尾递归编译器优化 累加器传递模式(APS) CPS函数 CPS变换 CPS尾递归 总结 累加器传递模式(Accumulator passing style) 尾递归优化在于使堆栈可以不 ...

  7. 跟我一起数据挖掘(22)——spark入门

    Spark简介 Spark是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行,Spark,拥有Hadoop MapReduce所具有的优点:但不同于MapR ...

  8. Maven常用插件

    maven利用各种插件来管理构建项目,本文记录下工作中常用到的插件及使用方法.每个插件都会提供多个目标(goal),用于标示任务.各插件配置在pom.xml里,如下: <build> [. ...

  9. DDN - Digital Data Network

    DDN(Digital Data Network,数字数据网)是一种利用光纤.数字微波或卫星等数字传输通道和数字交叉复用设备组成的数字数据传输网.它可以为用户提供各种速率的高质量数字专用电 数字数据网 ...

  10. css+div常用属性备忘录

    学习软件设计有一年多了,明年五月就要毕业了.回头看看发现自己其实挺差劲的. 最近开通了博客所以就整理了一下笔记,在这里发布一下自己以前学习css时总是记不住去翻书又很常用的属性,都是一些很基础的. 大 ...