通过引用和值传递WinForm的结果

时间:2014-02-07 10:08:55

标签: c# winforms data-structures

我有一个名为Form1的win窗体窗口 - 一个名为Label1的标签, 两个按钮分别名为button1和button2。

当我点击button1时,它会创建一个名为f的Form1类型的新窗口, 它本能化为当前窗口,即此(Form1), f是发送给名为ChangeByReference的方法作为参考。

ChangeByReference方法更改表单的文本,Label1的文本& ForeColor是 通过引用传递

当我点击button2时,这个实例方法将ChangeByValue命名为value。

ChangeByValue方法创建一个新窗口,初始化为Form1的默认构造函数, 然后将其设置为参数valForm,我更改一些属性,最后使用它来显示它 显示方法。

现在问题是为什么ChangeByValue方法调用正在破坏原始窗口 并显示新表单,因为它的参数是按值传递的?

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
        this.Text = "Original Window";
    }

    public void ChangeByReference(ref Form1 refForm)
    {
        Form1 f = refForm;
        f.label1.Text = "This is changed by Reference";
        f.label1.ForeColor = Color.Aquamarine;
    }

    public void ChangeByValue(Form1 valForm)
    {
        Form1 f = new Form1();
        f =  valForm;
        f.Text = "Changed Window";
        f.label1.Text = "This is changed by Value";
        f.label1.ForeColor = Color.Red;
        f.Show();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form1 f = this as Form1;
        ChangeByReference(ref f);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        ChangeByValue(this);
    }

}

2 个答案:

答案 0 :(得分:2)

方法ChangeByReference并不真正需要ref。您没有使用ref的“功能”。我认为你混合了两个概念,一个是“引用类型”,第二个是“传递参数作为参考”。另外,根据文件:

  

不要将引用传递的概念与引用类型的概念混淆。这两个概念不尽相同。无论是值类型还是引用类型,都可以通过ref修改方法参数。通过引用传递时,没有值类型的装箱。

来源:MSDN - ref (C# Reference)

在您的代码中,您只需更改作为参数传递的表单的某些属性。无论您是否将参数指定为ref,它都具有相同的效果。

在第二种方法ChangeByValue中,首先初始化一个新的Form1对象,但是在将局部变量重新分配给参数值之后。这样,新对象将不再使用(您将其“扔掉”)。因此,下一行代码实际上是通过参数更改/设置您提供的表单的属性。在这种情况下(来自button2_Click事件),您正在更改当前表单。

一篇有趣的文章:Parameter passing in C#(作者Jon Skeet)。

答案 1 :(得分:1)

按值传递valForm参数意味着更改valForm的引用不会更改传递变量的引用(在您的示例中为this)。

在您的方法中,您将f的引用分配给与valForm引用完全相同的对象,这意味着两个变量都指向同一个对象,即this。如果您通过一个引用修改该对象,它将反映在另一个引用中。