所有 C# 转换都会导致装箱/拆箱吗
我很想知道 C# 中的所有强制转换是否都会导致装箱,如果不是,那么所有强制转换都是成本高昂的操作吗?
示例取自 装箱和拆箱(C# 编程指南)
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
I am curious to know if all casts in C# result in boxing, and if not, are all casts a costly operation?
Example taken from Boxing and Unboxing (C# Programming Guide)
int i = 123;
// The following line boxes i.
object o = i;
This line obviously causes boxing (wrapping up the int type as an object).
This is an operation that is considered costly, since it creates garbage that will be collected.
What about casts from 2 different types of reference types? what is the cost of that? can it be properly measured? (compared to the previous example)
For example:
public class A
{
}
public class B : A
{
}
var obj = new B();
var obj2 = (A)obj; // is this an "expensive" operation? this is not boxing
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不会。只有装箱转换才会产生装箱,因此称为“装箱转换”。装箱转换都是从值类型到引用类型的内置转换——要么是值类型继承的类,要么是它实现的接口。 (或者通过协变或逆变引用转换到与其实现的接口兼容的接口。)
不会。标识转换的成本为零,因为编译器可以完全消除它们。
隐式引用转换是零成本。编译器可以完全消除它们。也就是说,从 Giraffe 转换为其基本类型 Animal,或者从 Giraffe 转换为其实现的接口类型 IAmATallMammal,都是免费的。
显式引用转换涉及运行时检查,以验证该引用确实引用了所需类型的对象。
运行时检查是否“昂贵”取决于您的预算。
当然。确定哪些资源与您相关(例如时间),然后用秒表仔细测量您的时间消耗。
一个你没有问但可能应该问的问题:
用户定义的转换只不过是方法调用的语法糖;与任何方法一样,该方法可能需要任意长的时间。
动态转换在运行时再次启动编译器;编译器可能需要任意长的时间来执行类型分析,具体取决于您选择向其抛出的分析问题的难度。
No. Only boxing conversions result in boxing, hence the name "boxing conversions". Boxing conversions are all built-in conversions from value types to reference types -- either to a class that the value type inherits from, or to an interface that it implements. (Or to an interface compatible with an interface it implements, via a covariant or contravariant reference conversion.)
No. Identity conversions are zero cost because the compiler can elide them entirely.
Implicit reference conversions are zero cost. The compiler can elide them entirely. That is, converting from Giraffe to its base type Animal, or Giraffe to its implemented interface type IAmATallMammal, are free.
Explicit reference conversions involve a runtime check to verify that the reference does in fact refer to an object of the desired type.
Whether that runtime check is "costly" or not depends on your budget.
Sure. Decide what resource is relevant to you -- time, say -- and then carefully measure your consumption of time with a stopwatch.
A question you did not ask but probably should have:
User-defined conversions are nothing more than a syntactic sugar for a method call; that method can take arbitrarily long, like any method.
Dynamic conversions start the compiler again at runtime; the compiler may take arbitrarily long to perform a type analysis, depending on how hard an analysis problem you choose to throw at it.
不。
装箱意味着将一个值放入新的引用类型实例中。
引用类型之间的标准转换不会导致任何分配。
(用户定义的强制转换可以做任何事情)
No.
Boxing means putting a value into a new reference type instance.
Standard casts between reference types do not result in any allocations.
(User-defined casts can do anything)
不会。装箱是一种非常特殊的操作,这意味着处理值类型的实例作为引用类型的实例。对于引用类型转换到引用类型转换,该概念不起作用。
简短回答:不。
详细回答:定义成本高昂。但仍然没有。
那么,如果它只是派生到基引用的转换怎么办?这速度快得惊人,因为什么也没发生。
其他用户定义的转换可能“慢”,也可能“快”。
这个是“慢”。
这个是“快”。
,不,这是“便宜”。
No. Boxing is a very special operation that means treating an instance of a value type as an instance of a reference type. For reference type conversion to reference type conversion, the concept plays no role.
Short answer: No.
Long answer: Define costly. Still no, though.
Well, what if it's just a derived to base reference conversion? That's BLAZINGLY fast because nothing happens.
Other, user-defined conversions, could be "slow", they could be "fast."
This one is "slow."
This one is "fast."
No, it's "cheap."