我很想知道C#中的所有演员阵容是否会导致拳击,如果不是,所有演员阵容都是一次代价高昂的操作?
取自Boxing and Unboxing (C# Programming Guide)
的示例 int i = 123;
// The following line boxes i.
object o = i;
这一行显然导致装箱(将int类型包装为一个对象)。 这是一项被认为代价高昂的操作,因为它会产生将要收集的垃圾。
来自2种不同类型的参考类型的演员表怎么样?那是多少钱?可以正确测量吗? (与前一个例子相比)
例如:
public class A
{
}
public class B : A
{
}
var obj = new B();
var obj2 = (A)obj; // is this an "expensive" operation? this is not boxing
答案 0 :(得分:23)
我很想知道C#中的所有转换是否都会导致拳击。
没有。只有拳击转换导致拳击,因此名称“拳击转换”。 Boxing转换是从值类型到引用类型的所有内置转换 - 要么是值类型继承的类,要么是它实现的接口。 (或通过协变或逆变参考转换,与其实现的接口兼容的接口。)
所有转换都是一项代价高昂的操作吗?
没有。身份转换是零成本,因为编译器可以完全忽略它们。
隐式和显式引用转换的成本是多少?
隐式参考转化为零成本。编译器可以完全忽略它们。也就是说,从Giraffe转换为其基本类型Animal,或Giraffe转换为其实现的接口类型IAmATallMammal,是免费的。
显式引用转换涉及运行时检查,以验证引用确实引用了所需类型的对象。
运行时检查是否“代价高昂”取决于您的预算。
可以正确衡量成本吗?
不确定。决定哪些资源与您相关 - 比如说时间 - 然后用秒表仔细衡量您的时间消耗。
你没有提出但可能应该提出的问题:
哪些转化费用最高?
用户定义的转换只不过是方法调用的语法糖;这个方法可以任意长,就像任何方法一样。
动态转换在运行时再次启动编译器;编译器可能会花费任意长的时间来执行类型分析,具体取决于您选择分析问题的难度。
答案 1 :(得分:10)
没有
装箱意味着将值放入新的引用类型实例。
引用类型之间的标准强制转换不会导致任何分配 (用户定义的强制转换可以做任何事情)
答案 2 :(得分:7)
我很想知道C#中的所有演员是否会导致拳击,
没有。 Boxing是very special operation,意味着将值类型的实例视为引用类型的实例。对于参考类型转换为引用类型转换,该概念不起作用。
所有演员都是一次代价高昂的演出?
简短回答:不。
答案很长:定义昂贵。但仍然没有。
来自2种不同类型的参考类型的演员表怎么样?那是多少钱?
那么,如果它只是派生到基准引用转换怎么办?那是快速的,因为没有任何反应。
其他用户定义的转换可能“慢”,它们可能“快速”。
这个“慢”。
class A { public int Foo { get; set; } }
class B {
public int Foo { get; set; }
static Random rg = new Random();
static explicit operator A(B b) {
Thread.Sleep(rg.Next());
return new A { Foo = b.Foo; }
}
}
这个是“快”。
class A { public int Foo { get; set; } }
class B {
public int Foo { get; set; }
static Random rg = new Random();
static explicit operator A(B b) {
return new A { Foo = b.Foo; }
}
}
var obj2 = (A)obj;
//这是一项“昂贵”的操作吗?这不是拳击
不,这是“便宜的”。