【问题标题】:Boxing and Unboxing装箱和拆箱
【发布时间】:2017-08-28 20:20:11
【问题描述】:

我对 C# 中的装箱和拆箱有一点疑问。

int i=1;
System.Int32 j = i;

以上代码可以称为拳击吗?

【问题讨论】:

  • 谢谢你,kalale aata。

标签: c# value-type boxing


【解决方案1】:

不,那根本不是拳击。 int 只是 System.Int32 的别名。该代码相当于:

int i = 1;
int j = i;

要发生装箱,必须转换为引用类型,例如

int i = 1;
object j = i;

或者:

int i = 1;
IComparable j = i;

【讨论】:

    【解决方案2】:

    只是为了稍微扩展乔恩的答案,当您调用基类的非覆盖或非虚拟方法时,也会发生装箱,例如

    i.GetType(); //boxing occur here
    

    或将int 传递给需要引用类型的方法

    void Foo(object obj) {}
    
    Foo(i); //boxing, no overload takes an int
    

    在第一个例子IL你可以清楚地看到box指令

    int i = 5;
    i.GetType();
    
    IL_0000:  ldc.i4.5    
    IL_0001:  stloc.0     // i
    IL_0002:  ldloc.0     // i
    IL_0003:  box         System.Int32    //<---- boxing
    IL_0008:  call        System.Object.GetType
    

    如果你的值类型中没有覆盖虚方法,它们在调用时也会被装箱

    enum MyEnum {}
    
    var e = new MyEnum();
    e.ToString(); //box will occur here, see IL for details
    
    IL_0000:  ldc.i4.0    
    IL_0001:  stloc.0     // e
    IL_0002:  ldloc.0     // e
    IL_0003:  box         UserQuery.MyEnum
    IL_0008:  callvirt    System.Object.ToString
    

    与结构相同的情况,除了它们将使用callvirt 操作码,如果需要,它将对结构进行装箱,

    【讨论】:

      【解决方案3】:

      没有。 int 是一个值类型。

      将值类型分配给对象时会发生装箱。

      【讨论】:

        【解决方案4】:

        这不是拳击

        intSystem.Int32 的别名。所以你的代码相当于;

        int i = 1;
        int j = i;
        

        对于装箱,应该有到对象或接口的转换。喜欢;

        int i = 1;
        object j = i;
        

        类类型的值可以转换为类型对象或 类实现的接口类型,只需处理 在编译时引用为另一种类型。同样,类型的值 对象或接口类型的值可以转换回 类类型而不更改引用(但当然是运行时 在这种情况下需要进行类型检查)。

        【讨论】:

          猜你喜欢
          • 2011-02-28
          • 1970-01-01
          • 1970-01-01
          • 2012-07-15
          • 1970-01-01
          • 2011-09-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多