none
兩個Form之間數值的問題 RRS feed

  • 問題

  • 小弟有個問題想請教一下

    程式有兩個Form分別為Form1、Form2

    Form1放了一個按鈕buttion1,Form2放了兩個按鈕btn_OK、btn_Cancel

    程式執行時,按下Form1的按鈕將struct1的數值傳到Form2的struct2,並開啟Form2

    Form2開啟後,按OK則stuct3修改的數值透過struct2傳回Form1給struct1

    如果按下Cancel則不回傳。

    但是現在不管按下OK或Cancel,只要一修改struct3的數值則struct1跟struct2的數值都會跟著變化。

    請問該怎麼修改,才可以修改struct3的數值但不改到struct1跟struct2呢?

    以下為Form1的程式

    public Form1()
            {
                InitializeComponent();
            }
    
            public struct struct1
            {
                public int X1;
            }
    
            struct1[] struct_1 = new struct1[2];
    
    
            private void button1_Click(object sender, EventArgs e)
            {
                struct_1[0].X1 = 0;
                struct_1[1].X1 = 0;
    
                Form2 frm2 = new Form2();
                frm2.struct_2 = struct_1;
                frm2.ShowDialog();
    
                if (frm2.bol_OK)
                {
                    struct_1 = frm2.struct_2;
                }
            }

    以下為Form2的程式

            Form1.struct1[] struct2;
            Form1.struct1[] struct3;
            bool bolOK = false;
    
            public Form1.struct1[] struct_2
            {
                get
                {
                    return struct2;
                }
                set
                {
                    struct2 = value;
                }
            }
    
            public bool bol_OK
            {
                get
                {
                    return bolOK;
                }
                set
                {
                    bolOK = value;
                }
            }
    
            private void Form2_Load(object sender, EventArgs e)
            {
                bolOK = false;
                struct3 = struct2;
    
                struct3[0].X1 = 1;
                struct3[1].X1 = 1;
                
            }
    
            private void btn_OK_Click(object sender, EventArgs e)
            {
                bolOK = true;
                struct2 = struct3;
    
                this.Close();
            }
    
            private void btn_Cancel_Click(object sender, EventArgs e)
            {
                bolOK = false;
                this.Close();
            }


    2015年4月6日 上午 06:58

解答

  • 在線上手冊會這樣告訴你

    當你使用等號時,實值型別是複製,參考型別是參照。

    換種說法。

    所有的等號,都是複製,實值型別複製的是變數實體,參考型別複製的是指標本體。

    由於參考型別是參照,也就是多一個變數指向該記憶體區塊,因此你透過別的參考變數存取的是相同的記憶體區塊。

    為了確保記憶體區塊不同,你必須自行複製記憶體區塊指給新變數。

    為了簡化其確保參考型別的多層包裝,建議你在你的結構內實作 Clone 方法,在該方法內才實際依據需求去 Clone ,讓封裝一致。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2015年4月7日 下午 12:12

所有回覆

  • 1) 沒有看到程式中有建立以下兩個陣列的動作:

       Form1.struct1[] struct2;

       Form1.struct1[] struct3;

    2) 在Form2的Load事件處理程序中, struct3 = struct2;這一行程式碼好像是多餘的:

        struct3 = struct2;

        struct3
    [0].X1 = 1;
        struct3
    [1].X1 = 1;

    2015年4月6日 上午 07:34
  • 原本應該是struct的定義是學生的姓名、座號、分數(即X1、X2、X3),

    struct1[0] -第一個學生、struct1[1] - 第二個學生

    但是PO上來怕程式太長就只放X1, 也只先宣告struct1長度為2

    原本的做法是stuct1內有一筆原始學生資料, 開啟Form2並將資料傳到struct2,在Form2顯示和修改

    struct3是用來顯示和暫存修改後的數值,所以Load的時候會先struct3 = struct2讓struct3內有數值

    接著操作修改後的資料 (即struct3[0].X1 = 1 struct3[1].X1 = 1) 都先暫存在struct3並顯示,

    如果要還原則再將原始的struct2的數值覆蓋回struct2

    整個修改完成在按下OK或Cancel

    但是現在變成修改strcut3的數值, struct1和struct2都會跟著改變

    我有試過如果struct1不要宣告成陣列就沒有這個問題

    2015年4月6日 上午 08:02
  • 您好,
    您可以使用 Array.Clone

    struct2 = ( Form1.struct1[] )struct3.Clone();

    詳細請參考:Array.Clone 方法


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2015年4月6日 上午 11:31
  • 請參考線上手冊關於

    實質型別

    參考型別

    兩種差異。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2015年4月6日 下午 12:54
  • 您的程式中沒有看到建立struct2和struct3的動作?
    2015年4月7日 上午 07:54
  • 我在網路上找到了這篇提到的

    C#][筆記] Value Type (實值型別) vs. Reference Type (參考型別)

    另外, 有人遇到相同問題的處理方法是採用迴圈一個一個搬

    C# 實值型別(value type)與參考型別(reference type)的Clone差異

    2015年4月7日 上午 10:37
  • 如果您的struct裡面都是 value type的話,可以直接用clone就可以了!

    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2015年4月7日 上午 11:09
  • 在線上手冊會這樣告訴你

    當你使用等號時,實值型別是複製,參考型別是參照。

    換種說法。

    所有的等號,都是複製,實值型別複製的是變數實體,參考型別複製的是指標本體。

    由於參考型別是參照,也就是多一個變數指向該記憶體區塊,因此你透過別的參考變數存取的是相同的記憶體區塊。

    為了確保記憶體區塊不同,你必須自行複製記憶體區塊指給新變數。

    為了簡化其確保參考型別的多層包裝,建議你在你的結構內實作 Clone 方法,在該方法內才實際依據需求去 Clone ,讓封裝一致。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2015年4月7日 下午 12:12
  • 感謝各位的幫忙, 因為我的陣列結構內還有一個陣列結構, 所以還是直接用For迴圈搬資料。

    不過這讓我多學了一課。

    2015年4月10日 上午 07:52