2009-09-21 69 views
2

我有兩種形式(Form1和Form2)。在Form1上有一個'public int i'變量,它在Form1構造函數中設置爲值1。 然後我打開窗體2從Form1中使用此代碼:通過兩個表單之間的引用傳遞參數

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

窗體2的構造是這樣的:

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

然後我把我在Form2變量值2和關閉窗體2。現在我期望Form1上的變量i具有值2(因爲'ref'關鍵字通過傳遞參數),但值仍然是1.我做錯了什麼,爲什麼ref關鍵字不工作在我的例子中?

感謝

回答

6

實際發生了什麼。

  1. 您創建一個名爲整數成員的object1「我」
  2. 你傳遞一個參考,以「我」到一個新的對象構造。對「我」的引用被稱爲「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(); 
    } 
} 

這可能是最簡單的方法來完成你要去的東西。

+0

我認爲,如果傳遞整數與ref關鍵字,它是傳遞對象相同的東西。感謝您清除 ,它現在起作用。 – sventevit 2009-09-21 13:21:09

+0

您也可以傳遞一個表單引用/實例而不是Object i – Jan 2016-12-19 12:49:48

6

的「裁判」修改不僅使構造函數調用本身中的任何差異。它只與參數 ...相關聯,並且在構造函數完成之後,該參數不再存在。

當您執行的任務:

i = x; 

,這只是複製。它不以任何其他方式將變量ix關聯。作爲一般的經驗法則:如果你不改變方法/構造函數中的參數值(在你的例子中你不這樣做),ref修改器沒有做任何事情。

你不能做你想做的事:你不能做一個字段(在這種情況下是Form2。i)某個其他變量的別名。

+0

我想補充一點,Form2已經暴露了一個public int i,所以他應該:從構造函數中刪除參數,設置f2.i = i;並在ShowDialog()讀取後與我= f2.il – configurator 2009-09-21 13:39:20

+1

我真的希望真正的代碼*沒有*有一個公共領域,但...該類並不真正叫做Form2,要麼:) – 2009-09-21 13:41:14

0
i = x; 

此聲明將i的值複製到x的值。要更改x,您需要在構造函數中爲其指定一個值。例如。

x=2; 
0

ref keyword作用域僅在聲明方法內:Form2構造函數。 一旦該方法退出,我在form1和我在form2不再鏈接(特別是因爲它們是ValueType)

0

我不知道你這樣做的原因,但我懷疑從對話框窗體中返回一個值並使用它來設置調用類中的變量會更好。否則,您會添加不必要的耦合到您的表單。

+0

如何將Form2中的值返回給Form1? – sventevit 2009-09-21 13:22:16

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

記住要記住所有這些內存管理。

0

感謝答案...

現在,我發現三種方式可以從窗體2取回變量到Form 1:

  • ,而不是正常的整數,傳遞形式之間的對象
  • 在Form1中,我可以使用get和set方法將'private int myVariable'和屬性'public int MyVariable'。然後,我可以把我的整個Form1以窗體2的構造,在那裏我可以訪問Form1.MyVariable財產
  • 指針

是否有任何其他的選擇嗎?這三個選項哪一個更好? (在我的例子,我需要從窗體2只能訪問一個整數到Form)

感謝

2

如果你真的希望能夠從窗體2中你可以使用一個回調方法設置在Form1中的變量。 (即通過在用於設置在Form1變量和從窗體2運行它的方法的地址)

像這樣:

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上設置一個公共屬性。

+0

非常有用! 10倍 – oCcSking 2014-01-16 19:46:36