2014-02-07 27 views
0

我有一個名爲Form1的贏窗體窗口 - 一個名爲Label1的標籤, 兩個按鈕分別命名爲button1和button2。通過引用和值傳遞WinForm的結果

當我點擊按鈕1時,它創建鍵入Form1名爲f的新窗口, 其inintialized到當前窗口,即這個(Form1中), f是發送到名爲ChangeByReference作爲參考方法。

ChangeByReference方法改變窗體的文本,Label1的文本&前景色是 參照

過去了,當我在BUTTON2點擊,名爲ChangeByValue作爲值這個實例方法。

ChangeByValue方法創建一個新的窗口中初始化爲默認Form1中, 然後將其設置爲參數valForm的構造函數,我改變了一些特性,最終顯示了使用 Show方法吧。

現在的問題是爲什麼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

ChangeByReference沒有方法真正需要的ref。您沒有使用ref的「功能」。我認爲你在混合兩個概念,一個是「引用類型」,另一個是「傳遞參數作爲參考」。此外,根據文檔:

不要混淆引用傳遞的概念與引用類型的概念。這兩個概念是不一樣的。無論是值類型還是引用類型,都可以通過ref修改方法參數。通過引用傳遞時,沒有值類型的裝箱。

來源:MSDN - ref (C# Reference)

在代碼中,你只需要改變你傳遞的參數形式的一些性質。無論您是否指定參數ref,它都具有相同的效果。

在您的第二個方法ChangeByValue中,首先初始化一個新的Form1對象,但在將局部變量重新分配給參數值之後。這樣,新的對象將不再使用(你「扔」掉了)。所以接下來的代碼行,你實際上正在改變/設置你通過參數提供的表單的屬性。在這種情況下(來自button2_Click事件),您正在更改當前表單。

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

+0

然後,我應該寫什麼,以便另一個窗口從ChangeByValue方法spanhdws –

+0

@RAZER只需刪除第二行('f = valForm;'),這將產生一個新的窗體。如果您想生成當前窗口的「副本」,則必須「克隆」當前窗體。 – Styxxy

+0

只需從您的方法中刪除第二行。 – Kapol

1

薪火valForm參數的值意味着改變valForm參考不會改變傳遞的變量的引用(在你的例子是this)。

在您的方法中,您將分配給f的引用與valForm引用的引用完全相同,這意味着兩個變量都指向相同的對象,即this。如果通過一個引用修改該對象,則會反映在另一個引用中。