【问题标题】:Pass parameter by reference between two Forms在两个表单之间通过引用传递参数
【发布时间】:2009-09-21 12:35:12
【问题描述】:

我有两个表格(Form1 和 Form2)。在 Form1 上有一个“public int i”变量,它在 Form1 构造函数中设置为值 1。 然后我使用以下代码从 Form1 打开 Form2:

Form2 f2 = new Form2(ref i);
f2.ShowDialog();

Form2 的构造函数如下所示:

public int i;
public Form2(ref int x)
{
    InitializeComponent();
    i = x;
}

然后我将 Form2 上的变量 i 设置为值 2 并关闭 Form2。现在我希望 Form1 上的变量 i 具有值 2(因为通过传递参数的 'ref' 关键字),但值仍然是 1。我做错了什么,为什么 ref 关键字在我的示例中不起作用?

谢谢

【问题讨论】:

    标签: c# pass-by-reference


    【解决方案1】:

    实际发生了什么。

    1. 您创建了一个带有名为“i”的整数成员的 object1
    2. 您将对“i”的引用传递给新的对象构造函数。对“i”的引用称为“x”。
    3. 您将“x”的值复制到第二个对象中的一个变量中,也称为“i”。
    4. 您退出了 object2 的构造函数。对 object1.i 的引用到此结束。
    5. 您修改了 object2.i(它是 object1.i 的副本,但不是引用、指针或链接)。 object1.i 未修改。

    有很多方法可以完成你想要的事情,或者通过事件,或者通过传入一个将在 object1 和 object2 之间共享的对象。

    Class Form1
    {
        Object i = new Object();
        ...
        public void DoSomething()
        {
            Form2 f = new Form2(i);
            f.Show();
        }
    }
    

    这可能是完成您的目标的最简单方法。

    【讨论】:

    • 我认为如果用 ref 关键字传递整数,它与传递对象是一样的。感谢您清除它,它现在可以工作了。
    • 你也可以传递一个表单引用/实例而不是 Object i
    【解决方案2】:

    “ref”修饰符仅在构造函数调用本身期间产生任何影响。它只与那个参数相关联...并且在构造函数完成后,那个参数就不再存在了。

    当你执行任务时:

    i = x;
    

    这只是复制。它不会以任何其他方式将变量 ix 相关联。

    作为一般经验法则:如果您不更改方法/构造函数中的参数值(在您的示例中没有更改),ref 修饰符不会做任何事情。

    你不能做你想做的事:你不能让一个字段(在这种情况下是Form2.i)成为其他变量的别名。

    【讨论】:

    • 我想补充一点,Form2 已经公开了一个公共 int i,所以他应该:从构造函数中删除参数,使用 f2.i = i 设置字段;在 ShowDialog() 之后用 i = f2.il 读回
    • 我真的希望真正的代码没有有一个公共字段......而且这个类也没有真正称为 Form2 :)
    【解决方案3】:

    我同意 Martin 的观点,即这种类型的解决方案会增加不必要的耦合,但如果你仍然坚持这样绑定,我认为使用简单的指针就可以了。

    class Form1 {  
      public int i;
      public void doSomething(){
        Form2 f = new Form2(&i);
        f.showDialog();
      }
    }
    

    然后在 Form2 中,您只需使用该指针即可。

    class Form2 {
      public int *i;
      public Form2(int *r){
        InitializeComponent();
        i = r;
      }
      public void setI(int v){
        *i = v;
      }
      public int getI(){
        return *i;
      }
    }
    

    记住要记住所有这些的内存管理。

    【讨论】:

      【解决方案4】:

      如果您真的希望能够在 Form2 中设置 Form1 中的变量,您可以使用回调方法。 (即传入设置 Form1 变量并从 Form2 运行它的方法的地址)

      类似这样的:

      public partial class Form1 : Form
      {
          public delegate void FormReturn(string s);
          private string var1;
      
          public Form1()
          {
              InitializeComponent();
          }
      
          private void button1_Click(object sender, EventArgs e)
          {
              var frm = new Form2(ReturnFunc);
              frm.ShowDialog();
          }
      
          protected void ReturnFunc(string text)
          {
              var1 = text;
          }
      }
      
      public partial class Form2 : Form
      {
          private Form1.FormReturn returnFunc;
      
          public Form2(Form1.FormReturn del)
          {
              InitializeComponent();
              returnFunc = del;
          }
      
          private void btnClose_Click(object sender, EventArgs e)
          {
              returnFunc.Invoke(txtText.Text);
              Close();
          }
      }
      

      虽然主要是矫枉过正。您可以在 form1 上设置一个公共属性。

      【讨论】:

        【解决方案5】:
        i = x;
        

        此语句将 i 的值复制到 x 的值。要更改 x 您需要在构造函数中实际为其分配一个值。例如。

        x=2;
        

        【讨论】:

          【解决方案6】:

          ref keyword 范围仅在声明方法内:Form2 构造函数。 一旦该方法退出,form1 中的 i 和 form2 中的 i 不再链接(特别是因为它们是 ValueType)

          【讨论】:

            【解决方案7】:

            我不知道你这样做背后的原因,但我怀疑从对话框表单返回一个值并使用它在调用类中设置变量会更好。否则,您将在表单中添加不必要的耦合。

            【讨论】:

            • 如何将值从 Form2 返回到 Form1?
            【解决方案8】:

            感谢您的回答...

            目前,我找到了三种将变量从 Form2 取回 Form1 的方法:

            • 不是普通的整数,而是在表单之间传递一个对象
            • 在 Form1 中,我可以使用 get 和 set 方法放置“private int myVariable”和属性“public int MyVariable”。然后我可以将整个 Form1 传递给 Form2 的构造函数,在那里我可以访问 Form1.MyVariable 属性
            • 指针

            还有其他选择吗?这三个选项哪个更好? (在我的示例中,我只需要从 Form2 访问 Form1 中的一个整数)

            谢谢

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-09-16
              • 2010-10-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多