代码之家  ›  专栏  ›  技术社区  ›  sventevit

在两个窗体之间通过引用传递参数

  •  3
  • sventevit  · 技术社区  · 16 年前

    我有两种表格(表格1和表格2)。在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。我做错了什么?为什么引用关键字在我的示例中不起作用?

    谢谢

    8 回复  |  直到 15 年前
        1
  •  6
  •   C. Ross trotttrotttrott    16 年前

    实际发生了什么。

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

    有很多方法可以实现您想要的,要么通过事件,要么通过传入一个对象来实现,该对象将在Object1和Object2之间共享。

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

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

        2
  •  6
  •   Jon Skeet    16 年前

    “ref”修饰符只在构造函数调用本身期间产生任何差异。它只和那个有关 参数 ……在构造函数完成之后,这个参数就不再存在了。

    执行任务时:

    i = x;
    

    那只是复制 价值 . 它没有关联变量 i 具有 x 以任何其他方式。

    一般的经验法则是:如果不更改方法/构造函数中参数的值(在示例中不更改),则 ref 修饰符什么也没做。

    你不能做你想做的:你不能 领域 (表格2) 在本例中)其他变量的别名。

        3
  •  2
  •   MLT    16 年前

    如果您真的希望能够从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上设置公共属性。

        4
  •  1
  •   dharga    16 年前

    我同意马丁的观点,这种类型的解决方案会增加不必要的耦合,但是如果你仍然坚持要像这样捆绑它,我认为使用一个简单的指针就可以做到这一点。

    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;
      }
    }
    

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

        5
  •  0
  •   Ash    16 年前
    i = x;
    

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

    x=2;
    
        6
  •  0
  •   manji    16 年前

    这个 ref keyword 作用域仅在声明方法:Form2构造函数内。 一旦该方法退出,Form1中的i和Form2中的i就不再链接(特别是因为它们是ValueType)

        7
  •  0
  •   MLT    16 年前

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

        8
  •  0
  •   sventevit    16 年前

    谢谢你的回答…

    现在,我发现了三种方法来将变量从Form2返回到Form1:

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

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

    谢谢

    推荐文章