C#-将一个对象强制转换为另一个类型有没有性能损失

C#-将一个对象强制转换为另一个类型有没有性能损失

夜无邪 发布于 2017-10-09 字数 562 浏览 1719 回复 2

看过一些东西,说装箱拆箱会带来性能损失,泛型可避免装箱拆箱带来的性能损失等等。

首先,对于装箱拆箱不是很了解,将一个对象强制转换为另一个类型是否属于装箱拆箱操作?object与另一个类型互转呢?

我的理解是强制转换只是编译期的事,运行时可以说没有性能损失。也就是说,数据在内存中就是固定存在的,类型只不过是对数据提出一种描述形式,告诉编译器该如何存取数据,换一个类型,有共同点的数据还是原样存取的。不知这种理解在C#中对不对。

抛开装箱拆箱不谈的话,强制转换,as转换,object与对象相互转换,等等,有没有性能损失,频繁操作下,性能损失可否忽略?

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

灵芸 2017-10-28 2 楼

补充一下:

int i = 3;
obj o = i; // 装箱;
int j = (o)i; // 拆箱
i.ToString(); // 装箱
IConvertable a = i as IConvertable; // 装箱

类型转换得分是转化为值类型还是引用类型,例如:值类型之间互相转换是把原有的对象赋值给了新的对象,例如:

int a = 3;
double b = a; // 产生两个对象,没有装箱操作,直接在栈上分配内存

强制类型转换不是编译期的事情而显然是运行期的事情,所谓泛型的操作性能要好一些,一般是指数组操作,例如:

ArrayList array = new ArrayList();
array.Add(3);
array.Add(4);

或者泛型实际在创建和操作时不需要和object之间进行类型转换的损失。

泛型的优势在于,对泛型进行操作时,会在应用程序域中生成类型的信息,而在下一次创建时可以直接获取泛型的信息来创建类型对象。

具体原理是泛型的信息会保存在元数据中,在第一次调用时获取泛型对应的类型签名,通过反射来创建对象,而在下一次获取泛型信息时,获取上一次缓存的类型信息即可。

对于基础类型例如int,float,double等,在进程创建时就已经加载了对应的类型信息,需要创建泛型类型信息的是指自定义类型。

抛开装箱拆箱不谈,类型转换、as、is当然是要有性能损失的,只不过这个损失是把没有类型的指针转为有类型的指针,例如C++中的(void *)转换为strongtype *的指针,找到对应的类型信息而已。所以性能损失可以忽略。

要注意的性能损失是指在自定义类型时要用typeof(MyType)而不是MyType t; t.GetType(); 原因在于typeof是获取缓存数据,而GetType需要进行计算。

以上是我的理解,欢迎提问。

想挽留 2017-10-27 1 楼

拆箱和装箱,其实和泛型没有直接关系.它的意义在于基本类型与其对应的对象类型之间的自动转换.比如int 与Integer之间的相互转化.long与Long之间的喜欢转换.基础类型的数据是生存在栈上的,而对象类型在堆里.每次转换都意味着堆中开辟了很的空间放置新的对象,或者堆中的对象失去了引用.在创建新对象时,是消耗资源的.

至于你说的对象之间的转换,除了每次判定一把是否合法之外,的确不会浪费什么资源.