为什么类型转换费用昂贵?类型转换需要什么?
好的,我得到它的价值类型,但让我们暂时排除它们。我们来谈谈引用类型之间的转换。如果我写这个:
class Animal { }
class Dog : Animal { }
示例1
var dog = new Dog();
object obj = dog;
示例2
public Animal GetAnimal()
{
return new Dog();
}
object obj = GetAnimal();
上述示例包含多少类型转换,为什么它们很昂贵?
据我所知,它只是一个新的4字节指针,必须在线程的本地参数堆栈上分配,新创建的引用指针的对象引用指向同一个旧地址。为什么这是一件昂贵的事情呢?是否分配了一个新的对象参考CPU密集型?然后,即使复制相同的对象引用也必须包含该成本,如下例所示:
Animal fish = new Animal();
Animal anotherFish = fish;
那个必须同样贵吗?
答案 0 :(得分:5)
对基类型的强制转换在运行时始终是空闲的。当你写:
Dog dog = new Dog();
object obj = dog;
JIT认为:
void* dog = new Dog();
void* obj = dog;
在这种情况下,JIT并不特别关心不同的引用类型。对它来说,所有的ref类型都只是指针。 JIT完全能够处理冗余的冗余变量和赋值。
对派生类的强制转换通常具有运行时成本,因为必须进行运行时检查。这有时可以优化。如果确实需要检查,它看起来有点像这样:
object obj = new Dog();
AssertCastValid<Dog>(obj);
Dog dog = obj; //Invalid C#, but OK for the JIT internally
使用AssertCastValid
代码来验证运行时类型。这是可能的样子(虽然它可能没有):
bool AssertCastToDogValid(object obj) { return obj.GetType() == typeof(Dog); }
(这是不正确的,但说明了这个想法。)
正如您所看到的,向上转播始终是免费的,而向下转发通常不是免费的。多么昂贵?这与你在代码中发生的其他事情有关,它取决于确切的情况(层次结构的深度,转换为接口,......)。