C#,結構成員是引用,會發生什麼
來源:互聯網
上載者:User
大家知道.結構(struct)是實值型別,類(class)是參考型別,現在我們考慮一個問題,如果結構裡面有參考型別的成員,那會產生什麼樣的情況?
現在我們有一個結構OneLine,先介紹一下它的特性,它對外基本可以看作是一行字串,但同時它又是由幾部分構成的,我舉個例:"ABCD",在某些應用中,我可能需要知道這個字串是由哪幾個元素構成的,是A/B/C/D還是ABC/D,而且考慮到這一行是可以添加的,所以我用了一個ArrayList來放入這些元素,以後調用的時候,就知道了,噢,是ABC/D,而不是A/B/C/D,從而作出相應的處理;
現在,我們來看我的測試代碼(附調試器圖片):
OneLine Line_1=new OneLine("test");
OneLine Line_2=Line_1;
OneLine Line_3=Line_1.Copy();
Line_1.Add("new_line");
return;
如果結構中的參考型別在結構被賦值給另一個結構的時候是複製一份副本,那麼Line_2和Line_3應該是一樣的.
我在寫一個程式時就這麼想當然了..結果出現了令人很抓狂的異常,見圖,比如你在下面的代碼裡使用Line_2的時候,你如果認為它裡面只有"test"這一個元素,錯誤就在所難免了.
找出了這個問題,我就寫了一個Copy方法,來返回這個結構的複製,問題就再也沒有出現,可以從圖上看到,Line_3按照我們的預期在運行.
最後,簡單表述一下今天這段異常讓我學習到的..
結構的賦值,應該是等同於類的淺層複製 (Shallow Copy)(成員是值就複製值,成員是引用就複製引用),而不是完全複製..
Appledotnet@hotmail.com 2004/07/08 附OneLine結構代碼見後
public struct OneLine
{
int Length;
string Line;
ArrayList AL;
public OneLine(string Line)//初始化
{
this.Line=Line;
this.Length=Line.Length;
this.AL=new ArrayList();
this.AL.Add(Line);
}
public bool Add(string newLine)//增加一行
{
foreach(object obj in AL)
if(((string)obj)==newLine)return false;
this.AL.Add(newLine);
this.Line=this.Line+newLine;
this.Length=this.Line.Length;
return true;
}
override public string ToString()
{
return Line;
}
public OneLine Copy()//返回一個複製的副本
{
OneLine OL=new OneLine(this.AL[0].ToString());
for(int i=1;i< AL.Count;i++)
OL.Add(AL[i].ToString());
return OL;
}
}