所以我明白拳击和拆箱是什么.什么时候出现在现实世界的代码中,或者在什么样的例子中出现问题?我无法想象做这样的事情:
int i = 123;
object o = i; // Boxing
int j = (int)o; // Unboxing
Run Code Online (Sandbox Code Playgroud)
...但这几乎肯定是极度过于简单的,我甚至可能在之前不知道它的情况下完成了装箱/拆箱.
Jon*_*eet 34
这是很多现在不再是一个问题比它之前的仿制药.现在,例如,我们可以使用:
List<int> x = new List<int>();
x.Add(10);
int y = x[0];
Run Code Online (Sandbox Code Playgroud)
根本不需要拳击或拆箱.
以前,我们有:
ArrayList x = new ArrayList();
x.Add(10); // Boxing
int y = (int) x[0]; // Unboxing
Run Code Online (Sandbox Code Playgroud)
这是我最常见的拳击和拆箱经验,至少.
如果没有泛型参与,我想我可能会说反思是我参与的项目中拳击的最常见原因.反射API总是使用"对象"来表示方法的返回值 - 因为它们没有其他方法可以知道要使用什么.
如果您不了解它,可能会发现的另一个原因是您使用实现接口的值类型,并将该值传递给另一个以接口类型作为参数的方法.同样,泛型使这不是一个问题,但如果你不知道它,它可能是一个令人讨厌的惊喜.
拳击(根据我的经验)通常发生在这些情况下:
Object
.ArrayList
).其他时候你可以看到装箱和拆箱是因为.NET框架的反射API大量使用反射Object
.
当将值类型(如struct,int,long)传递给接受引用类型的位置时,就会发生装箱/拆箱object
。
当您显式创建一个采用将传递值类型的object类型参数的方法时,会发生这种情况。当您使用较旧的非泛型集合来存储值类型(通常是基元)时,也会出现这种情况。
使用String.Format()
和传递原语时,您还将看到拳击发生。这是因为String.Format()
接受params object []-导致在调用中将其他参数装箱。
使用反射调用方法也可能导致装箱/拆箱,因为反射API只能选择返回,object
因为在编译时不知道实类型(并且反射API不能是泛型的)。
较新的通用集合不会导致装箱/拆箱,因此出于这个原因,较之较旧的集合(例如ArrayList,Hashtable等)更可取。更不用说它们是类型安全的。
您可以通过更改接受通用对象的方法来避免装箱问题。例如:
public void string Decorate( object a ) // passing a value type results in boxing
{
return a.ToString() + " Some other value";
}
Run Code Online (Sandbox Code Playgroud)
vs:
public void string Decorate<T>( T a )
{
return a.ToString() + " some other value";
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6487 次 |
最近记录: |