泛型(二)

来源:互联网 发布:数据库物理结构包括 编辑:程序博客网 时间:2024/06/05 08:12

泛型基础结构(Generics Infrastructure)


1、开放和封闭类型(Open and Closed Types)
带有泛型类型参数的类型仍是一种类型,称为开放类型(open type),不能创建该类型的实例;当所有的类型参数都有真实的数据类型时,该类型称为封闭类型(close type),可以创建该类型的实例。
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyGenerics2{    // define a static constructor on a generic type to     // ensure that the type argu-ments will meet certain criteria    internal sealed class GenericTypeThatRequiresAnEnum<T>    {        static GenericTypeThatRequiresAnEnum()        {            if (!typeof(T).IsEnum)            {                throw new ArgumentException("T must be an enumerated type");            }        }    }    // A partially specified open type    internal sealed class DictionaryStringKey<TValue> :        Dictionary<string, TValue> { }    class Program    {        static void Main(string[] args)        {            Object o = null;            // Dictionary<,> is an open type having 2 type parameters            Type t = typeof(Dictionary<,>);            // Try to create an instance of this type (fails)            o = CreateInstance(t);            Console.WriteLine();            // DictionaryStringKey<> is an open type having 1 type parameter             t = typeof(DictionaryStringKey<>);            // Try to create an instance of this type (fails)             o = CreateInstance(t);            Console.WriteLine();                     // DictionaryStringKey<Guid> is a closed type             t = typeof(DictionaryStringKey<Guid>);            // Try to create an instance of this type (succeeds)             o = CreateInstance(t);            // Prove it actually worked             Console.WriteLine("Object type=" + o.GetType());            Console.ReadKey();        }        private static Object CreateInstance(Type t)        {            Object o = null;            try            {                o = Activator.CreateInstance(t);                Console.WriteLine("Created instance of {0}", t.ToString());            }            catch (ArgumentException e)            {                Console.WriteLine(e.Message);            }            return o;        }    }}


2、泛型类型与继承(Generic Types and Inheritance)
泛型中明白指定类型参数不会影响继承层次有助于理解那些情况下需要使用强转,那些不需要。( Understanding that specifying type arguments doesn’t have anything to do with inheritance hierarchies will help you to recognize what kind of casting you can and can’t do)
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyGenerics3{    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;        }        public override string ToString()        {            return m_data.ToString() +                ((m_next != null) ? m_next.ToString() : string.Empty);        }    }    // 每个结点可以指定不同的类型(获得编译时类型安全,同时可以避免值类型的装箱)    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;        }        public override String ToString()        {             return m_data.ToString() +                 ((m_next != null) ? m_next.ToString() : String.Empty);         }     }    class Program    {        static void Main(string[] args)        {            SameDataLinkedList();            DifferentDataLinkedList();            Console.ReadKey();        }        private static void SameDataLinkedList()        {            Node<char> head = new Node<char>('C');            head = new Node<char>('B', head);            head = new Node<char>('A', head);            Console.WriteLine(head.ToString()); // Display "ABC"        }        private static void DifferentDataLinkedList()        {            Node head = new TypedNode<Char>('.');            head = new TypedNode<DateTime>(DateTime.Now, head);            head = new TypedNode<String>("Today is ", head);            Console.WriteLine(head.ToString());         }    }}



3、泛型的同一性(Generic Type Identity)

可以使用关键字using(使用别名)、var(类型推断)简化泛型类型的书写;不要使用类继承,这样将会失去同一性和相等性(lose type identity and equivalence)。
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyGenerics1{    using DateTimeList1 = System.Collections.Generic.List<System.DateTime>;    internal sealed class DateTimeList : List<DateTime>    {        // No need to put any code in here!     }    class Program    {        static void Main(string[] args)        {            IdentityTest();            Console.ReadKey();        }           public static void IdentityTest()        {            List<DateTime> ldt = new List<DateTime>();            DateTimeList dtl = new DateTimeList();            bool sameType = (typeof(List<DateTime>) == typeof(DateTimeList));            Console.WriteLine("List<DateTime>, DateTimeList:{0}", sameType);            sameType = (typeof(List<DateTime>) == typeof(DateTimeList1));            Console.WriteLine("List<DateTime>, DateTimeList1:{0}", sameType);        }    }}



4、代码爆炸(Code Explosion)

为每种类型或方法生成本地代码,会增加工作集,影响性能。
(When a method that uses generic type parameters is JIT-compiled, the CLR takes the method’s IL, substitutes the specified type arguments, and then creates native code that is specific to that method operating on the specified data types. This is exactly what you want and is one of the main features of generics. However, there is a downside to this: the CLR keeps generating native code for every method/type combination. This is referred to ascode explosion. This can end up increasing the application’s working set substantially, thereby hurting performance
CLR优化
1)相同的方法只编译一次,即使在完全不同的程序集里;
2)CLR认为所有应用类型参数式相同的(所用引用类型参数或变量都是指针,all reference type arguments or variables are really just pointers ),其代码可以共享。
List<stream>编译的方法List<string>可以使用。
0 0
原创粉丝点击