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次笔记所说。

  • 相关阅读:
    XHProf的安装和使用(PHP性能测试神器)
    Visual自动添加CSS兼容前缀
    webpack9--删除冗余的CSS
    Vue 获取自定义属性的值
    webpack8--删除dist目录,压缩分离后的CSS
    webpack7--css压缩成单独的css文件
    APICloud 真机连接失败
    js 实现遮罩某一部分
    js实现选集功能
    微信小程序——wxParse使用方法
  • 原文地址:https://www.cnblogs.com/haokaibo/p/2129247.html
Copyright © 2011-2022 走看看