【问题标题】:ref for variables not parameters in functions参考变量不是函数中的参数
【发布时间】:2011-02-07 10:02:25
【问题描述】:

假设我有一个Person 类并且有以下内容:

Person A = new Person("Tom");
Person B = A;

有没有办法可以改变它,这样如果我将一个新的Person 分配给BB = new Person("Harry")A 也会指同一个实例?我知道你可以在函数的 ref 参数分配中做到这一点。

【问题讨论】:

    标签: c# ref


    【解决方案1】:

    更新:此处描述的功能已添加到 C# 7。


    您想要的功能称为“ref locals”,它在 C# 中不受支持。

    CLR 确实支持生成包含 ref locals 的代码,并且几年前我编写了一个具有您想要的功能的 C# 的实验版本,只是为了看看它是否可以工作。你可以这样做:

    Person a = whatever;
    ref Person b = ref a;
    

    然后正如您所说,对“b”的更改会更改“a”的内容。这两个变量成为同一个存储位置的别名。

    虽然这是一个不错的小功能并且运行良好,但我们决定不将它用于 C#。有可能它仍然会发生在该语言的假设未来版本中,但我不会对此感到兴奋。它可能不会发生。

    (请记住,Eric 对任何 Microsoft 产品的假设未来版本的所有想法均仅用于娱乐目的。)

    【讨论】:

    • 这个有什么用吗?我现在想不出任何东西,除非我们想迷惑读者……
    • @configurator:如果您可以为变量创建别名并更改它引用的变量,则某些算法会变得更容易编写。在某些情况下,您可以提高某些性能敏感代码的速度。
    • @EricLippert 如果我没记错的话,最新版本的 c# 支持此功能。
    • @Zer0:感谢您的注意;我会更新文本。
    【解决方案2】:

    不,这在安全代码中是不可能的(除了ref 函数参数)。在不安全的代码中,您也许可以使用指针来实现这一点,但我认为这不是一个好主意。

    A 包含对“Tom”的引用作为值。您需要引用 A 来更改它指向的位置。

    如果我们考虑一种语言中的类似代码,它显式使用指针而不是将类的实例隐式视为引用:

    Person* A=new Person("Tom");
    Person* B=A;
    B=new Person("Harry");//Changes only B
    Person** C=&A;
    (*C)=new Person("John");//Now A changes
    

    所以你需要一个指向指针的指针才能改变A。如果将其传输到 C#,则需要对局部变量的引用。而这些仅以ref 函数参数的形式提供。这避免了一些生命周期问题,因为对局部变量的引用不能安全地超过该局部变量。

    如果这些不是私有变量,您可以使 B 成为在 setter 中修改 A 的属性。

    Person B{get{return A;} set{A=value;}}
    

    【讨论】:

    • 请注意:C# 确实支持与您的示例非常相似的指针。它们只是没有被广泛使用(正如我在回答中所写的那样)。
    • 是的,C# 在某些有限的上下文中确实支持指针。但在这种情况下,它没有为引用/指针使用明确的符号。如果您将Person 声明为类,则其类型的变量将被隐式视为指针/引用。
    【解决方案3】:

    没有直接的方法可以做到这一点。

    您可以采用源代码方法,例如:

    A = B = new Person("Harry")
    

    或者使用泛型类型。比如:

    var A = new ReferenceHolder<Person> (new Person("Tom")); 
    var B = A;
    

    在 C# 中,您也可以使用指针(基本上是 ref 类型),但这种方法不是静态可验证的,也不建议使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-28
      • 2021-12-02
      • 2011-10-27
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多