zoukankan      html  css  js  c++  java
  • Effective C# 学习笔记(四十五)减少装箱拆箱行为

    值类型用来存储数据,引用类型用来表现多态,而所有.net framework中的类型都继承自System.Object。这看起来有些冲突。.NET framework 用装箱和拆箱来解决两类类型间的转换。但是这种操作是十分消耗资源且影响性能的。

    装箱:把一个值类型放入一个未命名的引用类型中,以使得该类型可被当作引用类型使用。

    拆箱:从一个引用类型中将值类型的Copy取出。

    可以通过范型来避免装箱拆箱,但是.net中还是有许多方法是不支持范型方法的,所以这些方法的调用,在对待值类型时会引起自动的装箱拆箱行为。如下代码所示:

    Console.WriteLine("A few numbers:{0}, {1}, {2}", 25, 32, 50);

    上面的方法原来的参数列表是这样的Console.WriteLine(string,object[]),所以上面的253250三个int的值类型对象对自动进行装箱。其实在其内部的执行方法是这样的:

    private static void SampleThree()

    {

    object firstParm = 5;//装箱

    object o = firstParm;

    int i = (int)o; // unbox

    string output = i.ToString();

    }

     

    避免装箱拆箱的方法应该这样写:

    Console.WriteLine("A few numbers:{0}, {1}, {2}", 25.ToString(), 32.ToString(), 50.ToString());

     

    .NET framework 的集合类型存储的System.Object的引用类型,所以对于集合类型的范型,在传入值类型的类型参数时,会产生装箱操作。而当你讲一个对象从集合中取出,你就会从集合中得到该对象的一个拷贝。但这常常会引起一个bug。看如下带代码:

    public struct Person

    {

    public string Name { get; set; }

    public override string ToString()

    {

    return Name;

    }

    }

    // Using the Person in a collection:

    var attendees = new List<Person>();

    Person p = new Person { Name = "Old Name" };

    attendees.Add(p);

    // Try to change the name:

    // Would work if Person was a reference type.

    Person p2 = attendees[0];

    p2.Name = "New Name";

    // Writes "Old Name":

    Console.WriteLine(attendees[0].ToString( ));

     

    如上面的代码所示:Person类型是个值类型,在List<Person>类型的对象时你只修改的了该对象的一个Copy,即一个根据原对象新创建的对象,而没有修改集合中的值。这时你应该使用immutable值类型。如第20次笔记所说。

  • 相关阅读:
    Element 更新以及全局设置属性
    第二次作业
    软件工程---自我介绍
    git lfs
    SUID
    G1 log 解析
    CMS jvm flags详解
    java不安全证书报证书路径找不到问题
    记一次CMS unloading class 耗时长调查
    springboot jsp 在Linux中报404问题
  • 原文地址:https://www.cnblogs.com/haokaibo/p/2129247.html
Copyright © 2011-2022 走看看