【问题标题】:C# reference assignment operator?C# 引用赋值运算符?
【发布时间】:2011-12-12 06:54:02
【问题描述】:

例如:

        int x = 1;
        int y = x;
        y = 3;
        Debug.WriteLine(x.ToString());

它是不是任何引用运算符而不是第 3 行的“=”, 使 x 等于 3 ,如果我分配 y =3 。

【问题讨论】:

  • 没有。那没有。这以前就出现过,我记得 Eric Lippert 的反应很好。
  • 你能解释一下你为什么想要这样的东西吗?值类型不能这样做。
  • @Bala R 它与值与引用类型无关。问题是关于创建[对变量]的引用(在 C++ 中是可能的),而不是关于[对象]的可变性......当然,通常有“更好的方法”来解决这个问题。

标签: c# variables reference


【解决方案1】:

做到这一点的唯一方法是使用“不安全”的代码,并实际使用指针。指针不能存在于 C# 中的不安全代码块之外。然后,您应该能够像在 C/C++ 中一样使用指针

查看this 页面了解如何使用“不安全”代码块。

【讨论】:

    【解决方案2】:

    'int' 是一种值类型,因此正如您所发现的那样,在赋值时复制值。

    您可以通过使用“不安全”块来使用传统 C/C++ 意义上的指针,但指针只能在该块内使用,这限制了它的使用。相反,如果您想访问“不安全”块之外的值,则需要转换为使用引用。

    这样的……

    var x = new Tuple<int>(1);
    var y = x;
    y.Item1 = 3;
    

    【讨论】:

    • 请注意,如果 x 最初是类中的字段,则此解决方案可能不实用。在这种情况下,您可以改用 Eric Lippert 提供的 this code 来回答类似问题。
    • 注意:xy 可以是引用类型的局部变量,同样的道理也适用。 重新分配 y 不会影响 x。 关于值类型的部分无关紧要。
    【解决方案3】:

    这不是您要问的,但我认为它可能会有所帮助。如果你想在函数中使用指针别名,可以使用 ref 关键字,如下所示:

    public static void RefExample(ref int y)
    {
        y = 3;
    }
    
    main()
    {
        int x = 5;
        RefExample(ref x);
        Console.WriteLine(x); // prints 3
    }
    

    【讨论】:

      【解决方案4】:

      你可以像在C

      中那样使用指针
          int x = 1;
          unsafe
          {
              int* y = &x;
              *y = 3;
          }
      
          Debug.WriteLine(x.ToString());
      

      (请注意,您必须使用 unsafe 标志进行编译)

      【讨论】:

        【解决方案5】:

        我曾经编写过具有该功能的 C# 版本的原型;你可以说:

        int x = 123;
        ref int y = ref x;
        

        现在 x 和 y 将成为同一个变量的别名。

        我们决定不将该功能添加到语言中;如果你有一个非常棒的用例,我很想听听。

        您不是第一个询问此功能的人;有关详细信息,请参阅Can I use a reference inside a C# function like C++?

        更新:该功能可能会出现在 C# 7 中。

        【讨论】:

        • 这里有一个例子,如果能够在循环外将x 设为ij 会更好。 i.imgur.com/W12AMCN.png
        • 寻找 exact 相同的功能我发现了这个问题(以及许多其他问题)。我有一种我认为非常普通的情况,我看不到使用参考的体面解决方法。我想要的不涉及 C++ 的指针、内存地址或其他“复杂”功能。我需要一个简单的(“盲”)引用(别名),更多地指向来自 C++ 的#define。我对向/从函数传递/返回 ref 也不感兴趣,因此也不会有与堆栈相关的问题。以我的情况为例:
        • 情况:我有几个 int 变量,按下一个键(在一个循环中)我从现在开始“分配”一个作为工作变量。现在所有要遵循的工作(许多功能)都必须在那个特定的变量上(即按另一个键来读/写它)。我看不出如何避免不必要的/开销代码。 C++ 参考绝对完美。除了恕我直言,正如允许为 ref 类型传递值一样,反之亦然。
        • @mireazma:那么为什么不创建一个写入变量的 delegate 呢?那就是你的东西,它代表对变量的访问,而且,变量的生命周期被延长到委托实例的生命周期。
        • 另见Proposal: Ref Returns and Locals。请注意,它已于 9 月 19 日实施关闭,并显示在 docs.microsoft.com/en-us/dotnet/articles/csharp/csharp-7 上。因此,此功能可能在 C# 7 中可用。
        【解决方案6】:

        我想评论 Eric Lippert 的回答,但新用户无法发布帖子。所以,我想我有这样的用法。

        看看这段代码:

        private void SetGridColumns(ref RegistryKey targetKey, List<ColInfo> cols)
            {
                string targetKeyName = Path.GetFileName(targetKey.Name);
                m_grids.DeleteSubKeyTree(targetKeyName, false);
                targetKey.Close();
                targetKey = m_grids.CreateSubKey(targetKeyName);
        

        //... }

            public void SetColumns(List<ColInfo> cols, bool youth)
            {
                RegistryKey key = youth ? m_youthGrid : m_mainGrid;
                SetGridColumns(ref key, cols);
            }
        

        它应该像这样工作: 在 SetColumns 我调用 SetGridColumns 键取决于“青年”参数。我希望我的密钥首先被删除然后重新创建。 m_mainGrid 当然是一个类的成员。 在这种情况下,密钥确实被删除并重新创建。但重新创建的只是 SetGridColumns 中的“targetKey”,而不是我的 m_mainGrid。

        所以,我在这里唯一能做的就是使用指针,这在 C# 中不是首选方式。 如果我只能这样做:

        ref RegistryKey key = youth ? m_youthGrid : m_mainGrid;
        

        一切正常。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-29
          • 1970-01-01
          • 2021-08-10
          • 1970-01-01
          • 2010-12-18
          • 2016-04-01
          相关资源
          最近更新 更多