大家知道.結構(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按照我們的預期在運行.
最後,簡單表述一下今天這段異常讓我學習到的..
結構的賦值,應該是等同於類的淺表復制(成員是值就復制值,成員是引用就復制引用),而不是完全復制..
[email protected] 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;
}
}