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

转载于:https://www.cnblogs.com/haokaibo/archive/2011/08/06/2129247.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值