【问题标题】:Does unboxing occur when a class's value-type member is referenced?引用类的值类型成员时会发生拆箱吗?
【发布时间】:2012-02-07 06:13:19
【问题描述】:

我阅读了What is boxing and unboxing and what are the trade offs?,但无法理解一件事。假设我有一堂课:

class MyClass
{
    public int Value { get; set; }
}

我想在我的方法中获得价值:

void MyFunc(MyClass cls)
{
    int i = cls.Value;
}

作为一个放置在堆中的类,我猜 Value 也放置在堆中?因此操作

int i = cls.Value;

正在拆箱吗?还是不拆箱?

【问题讨论】:

  • 不,这不是拆箱,因为您要从一个 int 字段转到一个 int 局部变量。如果一侧是引用类型,则将是装箱/拆箱,因此如果 Value 是对象类型。

标签: c# .net unboxing


【解决方案1】:

别再想stackheap了;这是完全错误的思考方式。强调不是“装箱”意味着“在堆上”的情况,因此任何“在堆上”的东西都必须是“装箱”的。

栈和堆无关。相反,请考虑 referencesvalues值类型的值在必须被视为对对象的引用时被装箱。如果您需要对值类型的值进行引用,则制作一个框,将值放入框,并引用该框。在那里,现在您有了对值类型值的引用。

不要将其与引用值类型的变量混淆;那是完全不同的。变量和值是两个非常不同的东西。要引用一个变量,你可以使用“ref”关键字。

【讨论】:

  • @OlivierJacot-Descombes:我丝毫没有关注你。 Int 是一个值类型;没有 int 类。我怀疑您没有非常精确地推理对象具有类型意味着什么。装箱的 int 是 int 类型;未装箱的 int 也是 int 类型。我有一只猫;她是Felis Catus的物种。我把她放在一个盒子里,在地板上画了一个指向盒子的箭头。 她仍然属于猫科动物。盒装猫和未盒装猫都是猫;与整数相同。我不明白你在说什么。
  • 当鱿鱼和猫一起放在盒子里时,猫是活的还是死的,还是两者兼而有之?
  • @IgbyLargeman:这是生物学的基本问题:当你把两个生物放在一个盒子里时,哪个会吃掉另一个?
  • 虽然从 C# 的角度来看可能没有“盒装类型”这样的东西,但请注意,从 CLI 的角度来看是存在的(参见 ECMA CLI 第一部分的第 8.2.4 节规格)。 “对于每个值类型,CTS 定义了一个相应的引用类型,称为装箱类型。”但是,“不能直接通过名称引用盒装类型,因此不能为任何字段或局部变量赋予盒装类型。”
  • 是的,Igby,有一种神奇的独角兽类型。它的存在就像爱、慷慨和奉献一样肯定存在,你知道它们比比皆是,并为你的生活带来最高的美丽和快乐。唉!如果没有神奇的独角兽类型,世界将会多么沉闷!
【解决方案2】:

装箱或拆箱与将值存储在堆或堆栈上没有任何关系。你应该阅读the article "Boxing and Unboxing" from the C# Programming Guide。在您的示例中,这两个都没有发生,因为您将 int 分配给 int。

【讨论】:

    【解决方案3】:

    既不是unboxing,也不是boxing。 考虑到您分配给 int without 演员,我希望这段代码可以编译,这意味着 cls.ValueInteger(int) 类型。所以将int 分配给int。 这里发生的是值副本

    【讨论】:

      【解决方案4】:
      int i = 5;
      object o = i;   // boxing of int i
      int i = (int)o; // unboxing of object o
      

      请注意,我们不会将i 分配给对象的字段或属性,而是分配给对象本身。 它可以与光的性质相媲美。光可以被感知为由粒子(光子)构成或被视为波。 int 可以是 int 对象(引用类型)或 int 值类型。但是,您不能将 int 直接定义为引用类型;您必须将其转换为对象,例如通过将其分配给object 类型的变量、参数或属性或将其强制转换为object 以使其成为引用类型。

      【讨论】:

      • 所以当我说“((object)123).ToString()”时,那是不是拳击吗?因为要为其分配值的类型对象的变量参数属性在哪里?这个解释站不住脚。
      • 好吧,我忘记选角了! (我更改了文本)。
      • 好的,如果调用 123.GetType() 会怎样? GetType 是在 System.Object 上定义的非虚拟方法,因此需要对对象的引用作为其“this”参数。这不是拳击,因为没有分配或演员吗?你从错误的方向接近这个。 装箱是一种转换形式。这是这里的基础。
      • @EricLippert 转换从什么到什么?根据kvb对您的回答的评论,从CTS的角度来看,转换是从一个值类型到它的“相应引用类型称为盒装类型”。从这个角度来看,Olivier 的问题“boxed int 是什么类型”的答案是“boxed int”。我想这不是一个非常令人满意的答案。
      • @phoog:从 int 到 object 的转换是一种拳击转换。这是一种装箱转换,因为它分配了一个可以容纳 int 的盒子并将 int 复制到盒子中。
      猜你喜欢
      • 2014-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多