最近在寫乙個小工具,裡面用到了乙個自定義的類,並且需要對該類進行多個例項化。
因為需要根據需求來取不同的例項,所以決定將其放置到乙個字典中,以便取用。
另外,由於可能之後會改動例項化時的內容,所以準備將具體例項化的**封裝到乙個單獨的子程式中,以便更改。
所以寫了如下的**:
1結果發現,輸出的時候報錯了,提示在字典中該項對應的內容為null。namespace
example2,
11
12};
1314
private
void window_loaded(object
sender, routedeventargs e)
1519
20private
void initializationstaff() //
給變數新增例項21;
23 staff2=new myclass();24}
25}2627
class myclass
2833 }
而如果將**修改一下,在外面先例項化一下:
namespace此時,輸出的內容就正常了。example
,
};private
void window_loaded(object
sender, routedeventargs e)
private
void initializationstaff() //
給變數修改內容
}class myclass
}
那麼究竟這背後發生了什麼呢?
在請教過朋友後了解到,在c#中,為字典新增key對應的value時,實際上發生的效果是將目標內容複製到字典中,而並非是引用。
int a = 123;此時發生的是,系統首先找到一塊記憶體空間,把123這個值儲存到其中,並記錄該記憶體空間的位址a。
而在變數a中,實際儲存的內容就是位址a。
當我們將變數新增至字典中時:
dictionary dic = new dictionary() };字典首先找到a這個變數,得到了儲存著資料的位址a。
隨後將位址a中的內容複製,並貼上到字典開闢出的另一塊記憶體空間中。而這個記憶體空間的位址是位址b。
此時,無論我們給變數a如何賦值,字典中的a是不會改變的。
因為在給變數a賦值時,實際修改的是位址為a的記憶體空間中的資料,而字典中的a儲存在的位置是位址為b的記憶體空間中。
可是,如果按照這個結論來看,在本文開頭部分我用的第二種方法,也應該是在外部修改了類中成員的資料後,字典中的內容不變啊?
那為什麼在外部修改的時候字典內的內容也改變了呢?
當我們寫下以下**的時候:
1變數staff中,儲存了乙個位址a,位址a處儲存了myclass這樣的乙個型別,也就是a、b和c三個變數。namespace
example29
}1011class myclass
1217 }
而a、b和c三個變數,實際上是分別儲存了位址a,位址b,位址c。
這三個位址所指向的地方,才是各自儲存了資料的記憶體空間。
當我們將staff新增到字典中時,字典讀取到了位址a,並將位址a處儲存的內容複製到了自己新開闢的、在位址b處的記憶體空間中。
在複製的時候,a、b、c三個變數的位址也就隨著被複製到了位址b處中。
這個時候,外部的變數staff和字典中的staff,都會指向同樣的三塊記憶體空間。
當通過外部變數staff修改內容時,由於字典內的staff實際也訪問的是同樣的位址,所以字典內的內容也會隨之改變。
這樣說起來可能有點亂,用圖來表示應該會明了一些。
以上均為本人理解,如有疏漏還請各位多多指教。
C語言中不同型別變數的解讀
c語言中變數分為四類,分別是 四大類,所有變數必須先說明 定義 後使用。自動變數 區域性變數 區域性變數 在乙個函式開頭或段開頭處說明的變數,它有幾個特徵 include void print number int x,int y printf d n sum void main void 外部變數...
C 不同型別的畫筆!
畫筆是可以與graphics物件一起用來建立實心形狀和呈現文字的物件。1.solidbrush 畫筆最簡單形式,用純色進行繪製。2.hatchbrush 類似與 1 但它可以選擇大量預設圖案,而不是純色。要命名空間 using system.drawing.drawing2d 3.texturebr...
關於不同型別字元的轉換
一 string轉為ansistring 1 直接賦值 有警告 2 ansistring 型別強制轉換。無警告 二 ansistring 轉為string 1 直接賦值 有警告 2 string 型別強制轉換。無警告 三 string 轉為tbytes 1 bytes bytesof str 已轉為...