fel*_*eon 10 c# boxing value-type reference-type cts
在某些情况下,需要将值类型的实例视为引用类型的实例.对于这种情况,可以通过名为boxing的过程将值类型实例转换为引用类型实例.当盒式化值类型实例时,将在堆上分配存储,并将实例的值复制到该空间中.对此存储的引用放在堆栈上.盒装值是一个对象,一个包含值类型实例内容的引用类型.
在维基百科中有一个Java的例子.但是在C#中,有哪些情况需要打包一个值类型?或者更好/类似的问题是,为什么人们想要在堆上(盒装)而不是堆栈上存储值类型?
Ree*_*sey 14
通常,您通常希望避免装箱值类型.
但是,很少有这种情况有用.例如,如果您需要定位1.1框架,则无法访问泛型集合.在.NET 1.1中使用集合需要将您的值类型视为System.Object,这会导致装箱/取消装箱.
仍有一些情况可以在.NET 2.0+中使用.只要您想利用所有类型(包括值类型)可以直接作为对象这一事实,您可能需要使用装箱/拆箱.这有时很方便,因为它允许您在集合中保存任何类型(通过在通用集合中使用对象而不是T),但一般来说,最好避免这种情况,因为您正在失去类型安全性.但是,经常发生拳击的一种情况是,当你使用反射时 - 反射中的许多调用在处理值类型时需要装箱/拆箱,因为事先不知道类型.
拳击通常在必要时在.NET中自动发生; 通常当您将值类型传递给期望引用类型的东西时.一个常见的例子是string.Format().将原始值类型传递给此方法时,它们将作为调用的一部分进行装箱.所以:
int x = 10;
string s = string.Format( "The value of x is {0}", x ); // x is boxed here
Run Code Online (Sandbox Code Playgroud)
这说明了一个简单的场景,其中值类型(x)被自动装箱以传递给期望对象的方法.通常,您希望尽可能避免装箱值类型...但在某些情况下它非常有用.
有趣的是,当您在.NET中使用泛型时,当用作参数或类型成员时,值类型不会被加框.这使得泛型比旧的C#代码(例如ArrayList)更有效,它将{object}视为与类型无关的所有内容.这增加了使用泛型集合的另一个原因,例如List<T>或者Dictionary<T,K>over ArrayList或Hashtable.
我会推荐你2篇Eric Lippert的好文章
http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx
这是我100%同意的引用
将堆栈用于值类型的本地化只是CLR代表您执行的优化.值类型的相关特性是它们具有按值复制的语义,而不是有时它们的释放可以由运行时优化.
在99%的应用程序中,开发人员不应该关心为什么Value类型在堆栈中而不在堆中,以及我们可以在这里获得什么样的性能.Juts考虑到非常简单的规则:
任何规则都允许在特殊情况下排除,但不要尝试过度优化.
ps我遇到了一些具有2 - 3年经验的ASP.NET开发人员,他们不知道堆栈和堆之间的区别.:-(如果我是面试官,我不会聘请这样的人,但不是因为拳击/拆箱可能是我见过的任何ASP.NET网站的瓶颈.