zoukankan      html  css  js  c++  java
  • CLR Via CSharp读书笔记(12):泛型

    CLR允许创建 generic reference types 以及generic value types, 但是不允许创建 generic enumerated types.

    代码爆炸
    当一个使用泛型参数的方法被JIT编译时,CLR取出方法的中间语言(IL),替换指定的类型参数然后创建操作指定数据类型的方法的本地代码。CLR持续产生针对不同方法/数据类型组合的本地代码,这被称为代码爆炸。

    CLR有一些内建的优化器用以减少代码爆炸:
    首先,同一个AppDomain中不同的程序集均使用List<DateTime>, CLR仅会编译一次List<DateTime>。
    其次,CLR认为所有的引用类型都是等同的,因此,为使用List<String>参数的方法编译的代码,可以被使用List<Stream>参数的方法使用,因为所有引用类型参数事实上是指向位于堆上的对象的指针。所有针对指针的操作方法都一样。
    但是,如果类型参数是值类型CLR必须为该值类型生成指定的本地代码,因为不同的CPU指令被用于操作这些值类型,即使他们有相同的大小(size)。

    委托事实上就是有如下四个方法的一个类定义:构造函数,Invoke方法,BeginInvoke方法和EndInvoke方法。

     如果像下面这样定义了一个泛型委托:

    public delegate TReturn CallMe<TReturn, TKey, TValue>(TKey key, TValue value);

    编译器将其转换为类似于如下的一个类:

    public sealed class CallMe<TReturn, TKey, TValue>
    {
        public CallMe(Object obj, IntPtr method);
        public virtual TReturn Invoke(TKey key, TValue value);
        public virtual IAsyncResult BeginInvoke(TKey key, TValue value, AsyncCallback callback, Object obj);
        public virtual TReturn EndInvoke(IAsyncResult result);
    }

    主限制(primary constraint) -- zero or one

    引用类型(class)
    internal
    sealed class PrimaryConstraintOfClass<T> where T : class { public void M() { T temp = null;// Allowed because T must be a reference type } }
    值类型(struct):
    internal sealed class PrimaryConstraintOfStruct<T> where T : struct { public static T Factory() { // Allowed because all value types implicitly // have a public, parameterless constructor return new T(); } }

    辅助限制(secondary constraint) -- zero or more

     接口类型限制以及嵌套类型限制

    private static List<TBase> ConvertIList<T, TBase>(IList<T> list)
        where T : TBase
    {
        List<TBase> baseList = new List<TBase>(list.Count);
        for (Int32 index = 0; index < list.Count; index++)
        {
            baseList.Add(list[index]);
        }
        return baseList;
    }

    构造函数限制(constructor constraint) -- zero or one

    internal sealed class ConstructorConstraint<T> where T : new()
    {
        public static T Factory()
        {
            // Allowed because all value types implicitly
            // have a public, parameterless constructor and because
            // the constraint requires that any specified reference
            // type also have a public, parameterless constructor
            return new T();
        }
    }

    泛型类型和继承

    internal sealed class Node<T>
    {
        public T m_data;
        public Node<T> m_next;
    
        public Node(T data) : this(data, null){
        }
        public Node(T data, Node<T> next){
            m_data = data; 
            m_next = next;
        }
    }

    private static void SameDataLinkedList()
    {
        Node<Char> head = new Node<Char>('C');
        head = new Node<Char>('B', head);
        head = new Node<Char>('A', head); // 'A' 必须与'B'类型相同
        Console.WriteLine(head.ToString());
    }

    更好的方法:

    internal class Node
    {
        protected Node m_next;
        public Node(Node next){
            m_next = next;
        }
    }
    internal sealed class TypedNode<T> : Node
    {
        public T m_data;
    public TypedNode(T data) : this(data, null){ } public TypedNode(T data, Node next) : base(next){ m_data = data; } }

    private static void DifferentDataLinkedList(){
        Node head = new TypedNode<Char>('.');
        head = new TypedNode<DateTime>(DateTime.Now, head);
        head = new TypedNode<String>("Today is ", head); // 'Today is' 可以与DateTime.Now类型不同
        Console.WriteLine(head.ToString());
    }



  • 相关阅读:
    Delphi 中流的使用
    关于 Delphi 中流的使用(9) 分割与合并文件的函数
    基于Windows字库的点阵数据提取方法
    Oracle 后台进程介绍
    面试-MySQL
    怎样预置桌面上的应用程序图标、快捷方式图标或者窗体小部件?
    配置 Phpstorm + Xdebug + xampp
    [jQuery] 选择器和事件
    数据挖掘算法学习(四)PCA算法
    基础数位DP小结
  • 原文地址:https://www.cnblogs.com/thlzhf/p/2805438.html
Copyright © 2011-2022 走看看