鲜荣彬
Herry

在谈泛型的时候,必须说起C#的四种数值类型:即引用类型、(数)值类型、结构类型以及枚举类型,大多数人会将(数)值类型和结构类型统称为值类型。前面一直在说,使用泛型会大大提高程序的执行效率,之前一直没讲?现在来说一下其中的一个原因。IDE运行C#代码时,首先会将其解析成IL形式的程序集,然后才加载至内存的数据页,最后JIT编译器将IL转换成机器指令,生成的机器码才会被放置于只读的代码页中(因为我们的电脑只认识机器码,编程语言太高级了,它不认识)。

  对于非泛型类型,类的IL和其生成的机器码之间是一对的关系。

  JIT对泛型进行转换时,JIT将检查当前的类型参数,并根据该信息生成特定的指令,以便让不同类型参数能够使用同样的机器码。请记住,JIT会为所有的引用类型生成泛型类的一个机器码版本引用类型才会,值类型不管)。

  List<string> stringList=new List<string>();

  List<ClassType> otherList=new List<ClassType>(); //这里的IL代码是一样的

下面是一个使用XML序列化器对对象进行序列化,而非泛型的版本将允许传入任何类型。

 public static object LoadFromFile(Type typeToLoad, string filePath)
        {
            XmlSerializer factory = new XmlSerializer(typeToLoad);
            if (File.Exists(filePath))
            {
                using (TextReader r = new StreamReader(filePath))
                {
                    object rval = factory.Deserialize(r);
                    return rval;
                }
            }
            return default(object);
        }

        public static void SaveToFile(string filePath, object obj)
        {
            Type theType = obj.GetType();
            XmlSerializer factory = new XmlSerializer(theType);
            using (TextWriter w = new StreamWriter(filePath, false))
            {
                factory.Serialize(w, obj);
            }
        }

  也许有人不清楚Default的用法,这里插上一句,Default在泛型类和泛型方法中,在预先未参数类型时,将默认值分配给参数化类型 T。请看下面一个例子,可以很清楚的了解Default的功能。

  泛型类GenericList类似泛型的Add功能,将值插入到类似链表中的结构中。

 public class GenericList<T>
    {
        private class Node
        {
            public Node Next;
            public T Data;
        }

        private Node head = null;

        public void AddNode(T t)
        {
            Node newNode = new Node();
            newNode.Next = head;
            newNode.Data = t;
            head = newNode;
        }

        public T GetLast()
        {
            T temp = default(T);
            Node current = head;
            while (current != null)
            {
                temp = current.Data;
                current = current.Next;
            }
            return temp;
        }
    }

主函数Main

GenericList<int> gl1 = new GenericList<int>();
            gl1.AddNode(5);
            gl1.AddNode(4);
            gl1.AddNode(3);

            int intVal = gl1.GetLast();
            Console.WriteLine(intVal);

            GenericList<int> gl2 = new GenericList<int>();
            intVal = gl2.GetLast();
            Console.WriteLine(intVal);

            GenericList<string> gl3 = new GenericList<string>();
            GenericList<TestClass> xmls = new GenericList<TestClass>();
            gl3.AddNode("five");
            gl3.AddNode("fou");

            string sVal = gl3.GetLast();
            Console.WriteLine(sVal);

            GenericList<string> gll4 = new GenericList<string>();
            sVal = gll4.GetLast();
            Console.WriteLine(sVal);

            Console.WriteLine("end");

  这里的返回值为5,0,five, 。没错,你没看错,最后返回的一个值是空的字符串。

  在MSDN中对Default的解释为Default的作用是

给定参数化类型 T 的一个变量 t,只有当 T 为引用类型时,语句 t =  null 才有效;只有当 T 为数值类型而不是结构时,语句 t = 0 才能正常使用。 解决方案是使用 default 关键字,此关键字对于引用类型会返回 null,对于数值类型会返回零。 对于结构,此关键字将返回初始化为零或 null 的每个结构成员,具体取决于这些结构是值类型还是引用类型。 对于可以为 null 的值类型,默认返回 System.Nullable(Of T),它像任何结构一样初始化。

  这里暂时回到上面的XML序列化器的代码中,上面的序列化器中的代码你看出了什么问题吗?当然,请你用需求变化的眼观看待,否则,你看不出有什么问题,因为语法都是完全正确的,如何改进上述的序列类,后一篇我继续讲到。

 

  

posted on 2017-12-08 13:54  Herry彬  阅读(138)  评论(0编辑  收藏  举报