在两个表单之间通过引用传递参数

时间:2009-09-21 12:35:12

标签: c# pass-by-reference

我有两种形式(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关键字在我的示例中不起作用?

由于

8 个答案:

答案 0 :(得分:6)

“ref”修饰符仅在构造函数调用期间产生任何差异。它只与参数相关联......并且在构造函数完成后,该参数不再存在。

执行作业时:

i = x;

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

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

你无法做你想做的事情:你不能在这种情况下创建一个字段(Form2。i)一些其他变量的别名。

答案 1 :(得分:6)

实际发生了什么。

  1. 使用名为“i”
  2. 的整数成员创建object1
  3. 将对“i”的引用传递给新的对象构造函数。对“i”的引用称为“x”。
  4. 将“x”的值复制到第二个对象中的变量中,也称为“i”。
  5. 退出object2的构造函数。对object1.i的引用在这里结束。
  6. 您修改了object2.i(它是object1.i的副本,但不是引用,指针或链接)。 object1.i未被修改。
  7. 有许多方法可以通过事件或传入将在object1和object2之间共享的对象来完成您想要的任务。

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

    这可能是实现目标的最简单方法。

答案 2 :(得分:2)

如果您真的希望能够在Form2中从Form2中设置变量,则可以使用回调方法。 (即传入设置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上设置一个公共属性。

答案 3 :(得分:1)

我同意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 :(得分:0)

i = x;

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

x=2;

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

感谢您的回答......

目前,我找到了三种方法如何从Form2返回到Form1:

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

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

由于