[英]Under what circumstances would boxing occur in modern C#?
I'm trying to explain boxing to a junior colleague. 我正试图向一位初级同事解释拳击。
The canonical example seems to be ArrayList
. 规范示例似乎是
ArrayList
。 For example: 例如:
But this has been superseded by List<T>
from C# 2, when generics were introduced (as explained in this answer ). 但是,当引入泛型时,这已被C#2中的
List<T>
取代(如本答案中所述 )。
So, in the age of generics, under what circumstances would I find myself boxing values? 那么,在仿制药的时代,在什么情况下我会发现自己的拳击价值?
Edit: To be clear, I'm not asking whether it is still possible to use boxing. 编辑:要清楚,我不是在问是否仍然可以使用拳击。 I'm asking why we would use boxing now that generics have made
ArrayList
obsolete. 我问为什么我们会使用拳击,因为泛型已经使
ArrayList
过时了。
Edit 2: I thought this was already clear, but I'm also not asking about the difference between an ArrayList
and a List<T>
. 编辑2:我认为这已经很清楚了,但我也没有问过
ArrayList
和List<T>
之间的区别。 In fact, this question is entirely premised on the fact that I appreciate that generics mean we don't have to use an ArrayList
, and we therefore don't need to box values in these circumstances. 实际上,这个问题完全取决于我理解泛型意味着我们不必使用
ArrayList
这一事实,因此我们不需要在这些情况下设置值。
Boxing and unboxing is not something that you explicitly do; 拳击和拆箱不是你明确做的事情; it is something that happens all the time whenever you have a
struct
in your hands and you are passing it to some receiver that expects an object
. 只要你手中有一个
struct
并且你将它传递给一个需要一个object
接收器,它就会一直发生。 So, consider this code: 所以,请考虑以下代码:
public void SafeToString( Object a )
{
if( a != null )
return a.ToString();
return "null";
}
SafeToString( 42 );
If you had said 42.ToString()
there would be no boxing, because 42 is known by the compiler to have a ToString()
method, and struct
cannot be subclassed, so the ToString()
method that operates on 42 is known at compilation time. 如果你说过
42.ToString()
就没有装箱,因为编译器知道42有一个ToString()
方法,而struct
不能被子类化,所以编译时运行42的ToString()
方法是编译的时间。
However, when you say SafeToString( 42 );
但是,当你说
SafeToString( 42 );
the 42 gets boxed into an object, which is passed to SafeToString()
, which invokes Object.ToString()
, which resolves to the boxing object's ToString()
, which delegates to int.ToString()
. 42被装入一个对象,该对象被传递给
SafeToString()
,它调用Object.ToString()
,它解析为装箱对象的ToString()
,它委托给int.ToString()
。
Generics is a good thing, but they aren't capable completely remove the necessity of dealing with boxing. 泛型是一件好事,但他们无法完全消除处理拳击的必要性。
ArrayList
is obsolete, right, but sometimes you still going to use List<object>
when storing different types in one list (when only Object
is something they have in common). ArrayList
是过时的,对,但有时你仍然会在一个列表中存储不同类型时使用List<object>
(当只有Object
是他们共同的东西时)。
Another example generic methods. 另一个通用方法示例。 Again, they are good if you know type at compile-time, but what if you want something to work with any type?
同样,如果您在编译时知道类型,它们也很好,但是如果您想要使用任何类型的东西怎么办? Good old
object
parameter and boxing (with casting) to the rescue. 好老
object
参数和拳击(用铸造)来救援。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.