【问题标题】:Setting a type reference type to null doesn't affect copied type?将类型引用类型设置为 null 不会影响复制的类型?
【发布时间】:2011-11-09 17:59:40
【问题描述】:

为什么会产生“0”?

object a = 0;
object b = a;
a = null;
Console.WriteLine(b.ToString()); // Produces "0"
Console.Read();

b 不是指向同一个位置并且设置 a = null 会有效地使 b 为 null 吗?

【问题讨论】:

    标签: c# .net reference-type


    【解决方案1】:

    一张图抵千言:

    设置a = null 会删除a 对对象(装箱整数0)的引用(箭头)。它不会影响对象本身。 b 之后仍然引用未更改的对象。

    【讨论】:

    • 那么无论“a”是如何定义的,它永远都只是对“某个对象”的引用?还是没有办法设置“a”,这样当我们做“a=null”时,“some object”也被设置为null?
    • 您可以选择使用引用类型或值类型。在这种情况下可为空值类型。 intdouble 等原始类型和结构是值类型。值类型的变量包含“对象”本身。如果将int?(与Nullable<int> 相同)变量设置为null,则此“对象”为空;但是,您不能让两个变量成为同一个“对象”。一个值类型的赋值(例如int? b = a;)总是创建这个对象的一个​​副本,除非你把它分配给一个引用类型(比如System.Object),然后它会被装箱在一个新创建的引用类型对象中。跨度>
    • 再次感谢。所以你是说如果 a 和 b 都被声明为 System.Object,那么它们是(并且都代表)“某个对象”?我理解正确吗?
    • 当您将一个变量分配给另一个变量时,您总是复制一个值。碰巧在引用类型的情况下,这个值是一个引用。拳击是一个特例。请参阅:Boxing and Unboxing (C# Programming Guide)
    • 装箱 any 仅适用于值类型。当将值类型分配给引用类型变量(类或接口)时,会创建一个新的(引用类型)对象作为该值的包装器。 C# 会自动为您执行此操作。
    【解决方案2】:

    您想知道 cookie 在哪里。你有一张纸,标有“A”。纸上用铅笔写着“芝麻街 123 号”。

    纸不是饼干。该地址不是 cookie。该文件包含对包含 cookie 的地址的引用。

    您获得第二张纸,标有“B”。在这张纸上,您制作了“A”内容的副本。现在你有两张纸,都写着“芝麻街 123 号”。两者都会告诉你 cookie 在哪里。

    你拿一张纸“A”擦掉它。 “A”不再指 cookie 的位置。 B 仍然如此。

    您假设说“b = a”意味着在 B 上写“关于 cookie 的位置,请参阅纸 A”。但这不是 C# 中“b = a”的意思;这意味着制作参考的副本,而不是制作参考的别名

    在 C# 中使用“ref”关键字为引用创建别名,这很容易混淆:

    void M(ref object b)
    {
        b = null;
    }
    ...
    object a = 0;
    M(ref a);
    // "b" now becomes an alias for "a"; when "b" is nulled out, so is "a" because they are the same variable with two different names.
    

    在 C# 中,您只能在调用像这样采用 ref 参数的方法时执行此操作。 C# 不支持您想要的功能,但我们考虑过支持它:

    object a = 0;
    ref object b = ref a;
    a = null; // b and a are aliases for the same variable now.
    

    您是否迫切需要此功能?如果你这样做,请告诉我它是什么。这将帮助我们优先考虑该功能是否值得在假设的未来 C# 版本中使用。

    更新:完成了!此功能已添加到 C# 7。

    【讨论】:

    • 我不确定 OP 是否假设“b = a”的意思是“对于 cookie 的位置,请查阅论文 A”。我读这篇文章时假设“a = null”的意思是“从纸 A 上的位置删除 cookie”。
    • 我有一个问题,将“a”设置为NULL后,堆栈中是否还会有一个名为“a”的条目为空值,或者将其设置为NULL是否意味着直接删除该条目从堆栈中?
    • @TamerM:将变量设置为 null 不会“删除”该变量;如果您稍后尝试说if (a==null) 怎么办?
    • 从 C# 7.0 开始,我们有 ref returns and ref locals!
    【解决方案3】:

    您将 reference 设置为 null,您并未更改引用指向的对象ab 是两个独立的引用,因此将a 设置为null 当然会使b 保持不变(想想“指针”),它只是意味着a now 指向null(“无处” ")。

    【讨论】:

      【解决方案4】:

      装箱(这里发生的过程)在following article 中有很好的解释,并举例说明了内存中发生的情况。

      【讨论】:

        【解决方案5】:

        下面是对正在发生的事情的描述:

        object a = 0; // pointer a = 0xSomeA
        object b = a; // pointer b = 0xSomeB
        a = null; // nulling a, now 0x00; b still the same
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-02-13
          • 1970-01-01
          • 2019-12-04
          • 2011-03-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-16
          相关资源
          最近更新 更多