【问题标题】:Passing with ref keyword使用 ref 关键字传递
【发布时间】:2015-05-30 18:57:55
【问题描述】:

我在一个主窗体中有 2 个标签页(tabA 和 tabB)。假设我在主窗体初始化时将tabA 传递给tabB

tabB = new TabB(tabA);

所以我观察到的是,在更改 tabA(比如tabA.Text)内部的值后,tabBtabB.tabA.Text)内部的值也会发生变化。

所以我的理解(来自 C++)是这类似于传递引用。所以我的问题是如果我写这个有什么区别?

tabB = new TabB(ref tabA);

【问题讨论】:

    标签: c#


    【解决方案1】:

    您对 C++ 的类比是不正确的。在 C# 中传递引用对象* 类似于在 C++ 中通过指针传递对象,不同之处在于 C# 不需要星号来取消引用这些指针。

    在 C# 中通过引用传递类似于在 C++ 中通过引用传递指针:除了在函数中使用该指针外,您还可以为其分配一个新值,从而更改指针的值在调用者中。

    这是一个简短的插图:

    void One(List<int> list) {
        // Reassignment of the list is local to method One
        list = new List<int> {1, 2, 3};
    }
    void Two(ref List<int> list) {
        // Reassignment of the list is visible in the caller
        list = new List<int> {1, 2, 3};
    }
    ...
    var demo = new List<int> {5, 6, 7};
    One(demo);
    // Here the list remains [5, 6, 7]
    Two(ref demo);
    // Here the list becomes [1, 2, 3]
    

    * 与复制的值对象(例如structs 和原语)相反。

    【讨论】:

    • 正是我的想法!
    【解决方案2】:

    不同之处在于,如果您在TabB 构造函数中更改了tabA 参数指向的对象tabA 也会使用新对象。

    实际上没有办法传递对象本身,但您可以进行复制/克隆,这看起来就像原始对象一样。已经写了a good answer 用于复制Windows 控件的一般情况,an answer 仅用于选项卡。

    【讨论】:

      【解决方案3】:

      不同之处在于,通过使用ref 关键字,您可以更改引用本身,而不仅仅是引用所指向的对象。

      void funcA(TabA tabA)
      {
         // setting tabA to null here has no effect outside this function
         tabA = null;
      }
      
      void funcB(ref TabA tabA)
      {
         // setting tabA to null persists outside this function
         // and changes the actual reference passed in.
         tabA = null;
      }
      
      // tabA initialized to non-null
      tabA = new TabA();
      
      funcA(tabA);
      
      // tabA is still not null
      
      funcB(ref tabA);
      
      // tabA is now null
      

      【讨论】:

        猜你喜欢
        • 2013-12-31
        • 2015-03-13
        • 2012-11-19
        • 2017-02-11
        • 2011-01-12
        • 1970-01-01
        • 2010-12-13
        • 1970-01-01
        相关资源
        最近更新 更多