【问题标题】:Under what circumstances would boxing occur in modern C#?现代 C# 在什么情况下会出现拳击?
【发布时间】:2017-05-11 21:19:01
【问题描述】:

我正试图向一位初级同事解释拳击。

典型的例子似乎是ArrayList。例如:

但这已被 C# 2 中的 List<T> 取代,当时引入了泛型(如 this answer 中所述)。

那么,在泛型时代,在什么情况下我会发现自己装箱值?


编辑: 明确地说,我不是在问是否仍然可以使用拳击。我在问,既然泛型已经使 ArrayList 过时了,为什么我们还要使用拳击。


编辑 2: 我认为这已经很清楚了,但我也不是在问 ArrayListList<T> 之间的区别。事实上,这个问题完全基于这样一个事实,即我理解泛型意味着我们不必使用ArrayList,因此我们不需要在这些情况下对值进行装箱。

【问题讨论】:

  • 如果你这样做:object x = (object) 24;,你已经装箱了。
  • 什么都没有改变 - 条件是一样的
  • ArrayList 不是唯一接受对象的类,DataTable 和许多其他类也是如此。这只是 .NET,有许多公共接口可以获取或返回对象,或者您自己的代码也可以这样做。
  • @TomWright -- 这与您提出问题的方式完全不同。你的标题说的是“何时”而不是“为什么”。
  • 接口。尤其是与令人讨厌的过时第三方组件的接口。

标签: c# boxing


【解决方案1】:

装箱和拆箱不是您明确要做的事情;每当您手中有struct 并且您将其传递给期望object 的某个接收器时,总会发生这种情况。所以,考虑一下这段代码:

public void SafeToString( Object a )
{
    if( a != null )
        return a.ToString();
    return "null";
}

SafeToString( 42 );

如果你说42.ToString()就没有装箱了,因为编译器知道42有一个ToString()方法,而struct不能被子类化,所以对42操作的ToString()方法是在编译时已知。

但是,当您说SafeToString( 42 ); 时,42 被装箱到一个对象中,该对象被传递给SafeToString(),它调用Object.ToString(),它解析为装箱对象的ToString(),它委托给int.ToString()

【讨论】:

【解决方案2】:

泛型是个好东西,但它们并不能完全消除处理拳击的必要性。

ArrayList 已经过时了,对,但有时在一个列表中存储不同类型时,您仍然会使用 List<object>(当它们的共同点只有 Object 时)。

另一个示例泛型方法。同样,如果您在编译时知道类型,它们是很好的,但是如果您想要使用任何类型的东西怎么办?好老的object 参数和拳击(带铸造)来救援。

【讨论】:

猜你喜欢
  • 2020-01-26
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 2022-01-24
  • 2014-07-13
相关资源
最近更新 更多