zoukankan      html  css  js  c++  java
  • 关于范型

    范型是提高面向对象程序多态性设计衍生的。 
    1,C# 多态性设计回顾和展望
    在引入范型这个概念之前,回顾一下1.0或1.1中关于的Object类型的定义:
    Object类型是.NET Framework中System.Object的一个别名,可以分配任何类型给Object类型的变量。
    通过object类型的引入,实现了.NET对于面向对象程序多态设计。
    因为Object本身是一个引用类型,是存放在Heap(堆)上的。对于其他引用类型和Object转换很容易实现。
    而值类型和Object类型转换需要引入两个用于object类型和值类型转换概念boxing和unboxing.
    (1)boxing 装包
    将转换一个值类型到Object类型,
    例如:int i = 1; //存储在栈上
    object o = (object) i;//存储在堆上
    上面的代码在IL中将会是box [mscorlib]System.Int32
    将Int32和1同时装入一个Object对象中,结构如下:
    object[{Int32}-{1}];//前者表示boxing类型,后者表示其值
    (2)unboxing 拆包
    将一个已装包为Obect类型的值类型转换回值类型
    操作分为两部分组成:
    a,首先检查是否转换回的类型是装包的类型,如果不是抛出一个InvalidCastException运行时错误.
    b,复制Object类型中的值到目标值类型变量;
    例如:
    int i = 1;
    object o = (object) i; //boxing
    int j = (int)o //unboxing
    //double d = (double)o ,出现运行时错误


    通过上面的可以看到在.NET Framework 1.0 中使用object对象设计的多态性比C++的template(一种基于类似宏的编
    译时替换)执行效率增加了大量的copy的开销。所以在.NET Framewrok 2.0中引入范型来提高高面向对象程序多态性
    设计。

    2,范型概念和特点:
    范型的设计是为了解决上面提到过的Object的多态性设计中的两个问题:
    (1),性能上面的,boxing和unboxing需要大量的复制开销;
    (2),安全性上面的,在上面一个例子看到了如果unboxing类型不同会抛出一个InvalidCastException异常;
    范型的设计格式是使用<和>封闭其中一个范型参数,例如:
    public class Stack<T>;
    范型的实例化格式是使用需要使用的类型替换<和>封闭其中一个范型参数,例如:
    Stack<char> char_Stack = new Stack<char>();
    多范型类定义格式,在<和>封闭多个范型参数,例如:
    class Node<K,T>
    对于C++程序员,看上面关于范型的格式很快联系到了ISO C++当中的Template;
    的确两者语法上面非常相似,但是两者的多态性编译和实现有很大不同.
    在C++的Template编译后,没有编译带有Template的代码.而是通过一种宏的方式进行的替换过程.
    每次使用Template类型,编译器都会生成一个对应的类型代码.而不管是否个类型代码已经使用过了.
    在C#2.0中范型是在中间语言(IL)和公共语言运行时(CLR)支持的.
    对于值类型:会在JIT编译时候替换参数类型,如果存在以及编译特定类型的机器代码,将直接返回这段代码.
    这样避免了在ISO C++中Template可能带来代码膨胀.
    对于引用类型:会直接在JIT编译时候替换参数类型.
    理解C# 2.0范型是在实现是基于CLR支持的很重要啊,因为.NET的本质是和语言无关的.任何语言最后都是编译为中
    间语言,这样基于IL和CLR支持的范型可以运用到所有基于CLR实现的语言,例如:Visual Basic 2005等等.
    3,范型和其他类型执行效率对比例子
    下面分别是使用Int,Object和范型构造的3个栈的类

    代码
    /// <summary>
    /// Int类型实现的栈
    /// </summary>
    class IntStack
    {
    private int[] data;
    private int current;
    private int length;
    public IntStack(int Length)
    {
    length
    = Length;
    current
    = 0;
    data
    = new int[length];
    }
    public int Top()
    {
    return data[current - 1];
    }
    public void Push(int Data)
    {
    if (current < length)
    {
    data[current
    ++] = Data;
    }
    }
    public void Pop()
    {
    if (current > 0)
    {
    current
    --;
    }
    }
    }
    /// <summary>
    /// 范型的栈
    /// </summary>
    /// <typeparam name="T">范型</typeparam>
    class TemplateStack<T>
    {
    private int length;
    private int current;
    private T[] data;
    public TemplateStack(int Length)
    {
    current
    = 0;
    length
    = Length;
    data
    = new T[length];
    }
    public T Top()
    {
    return data[current - 1];
    }
    public void Push(T Data)
    {
    if (current < length)
    {
    data[current
    ++] = Data;
    }
    }
    public void Pop()
    {
    if (current > 0)
    {
    current
    --;
    }
    }
    }
    /// <summary>
    /// Object的栈
    /// </summary>
    class ObjectStack
    {
    private object[] data;
    private int current;
    private int length;
    public ObjectStack(int Length)
    {
    length
    = Length;
    current
    = 0;
    data
    = new object[length];
    }
    public object Top()
    {
    return data[current-1];
    }
    public void Push(object Data)
    {
    if (current < length)
    {
    data[current
    ++] = Data;
    }
    }
    public void Pop()
    {
    if (current > 0)
    {
    current
    --;
    }
    }
    }

    通过测试直接使用Int的栈和范型构造Int栈的开销接近.
    而比较前面两个Object每增加一次unboxig开销是增加的2倍.

    4,附录.NET 2.0 Framework 范型容器列表:

    Comparer<T>      Comparer   比较 
    Dictionary<K,T> HashTable hash表
    LinkedList<T> LinkList 链表
    List<T> ArrayList 数组链表
    Queue<T> Queue 队列
    SortedDictionary<K,T> SortedList 排序链表
    Stack<T> Stack 栈
    ICollection<T> ICollection 容器接口
    IComparable<T> System.IComparable比较接口
    IDictionary<K,T> IDictionary 字典接口
    IEnumerable<T> IEnumerable 枚举接口
    IEnumerator<T> IEnumerator 跌代接口
    IList<T> IList 链表接口
    参考资料:
    《Design and Implementation of Generics for the .NET Common Language Runtime》
    ---Andrew Kennedy Don Syme (Microsoft Research, Cambridge, U.K.)
    《An Introduction to C# Generics》
    ---Juval Lowy IDesign (MSDN Online)
    《C# Programmer's Reference》
    ---MSDN Library (MSDN Online)

    原文:http://zhidao.baidu.com/question/60939876
  • 相关阅读:
    什么是守护线程?
    如何优雅地停止一个线程?
    如何创建、启动 Java 线程?
    什么是线程?什么是进程?为什么要有线程?有什么关系与区别?
    并行是什么意思?与并发的区别是什么?
    并发编程的缺点?
    BZOJ_3058_四叶草魔杖_kruscal+状压DP
    BZOJ_3476_[Usaco2014 Mar]The Lazy Cow_扫描线+切比雪夫距离
    BZOJ_1511_[POI2006]OKR-Periods of Words_KMP
    BZOJ_3479_[Usaco2014 Mar]Watering the Fields_Prim
  • 原文地址:https://www.cnblogs.com/poissonnotes/p/1772655.html
Copyright © 2011-2022 走看看