object[] objs = new object[]{"one","two","three"};
存儲在字符串數組中以字符串的引用對象字符串如何存儲在對象數組中?
[@] - one
[@] - two
[@] - three
或是存儲在數組元素的字符串對象?
[one][two][three]
謝謝。
編輯:對不起,我的幻想圖失敗慘敗。
object[] objs = new object[]{"one","two","three"};
存儲在字符串數組中以字符串的引用對象字符串如何存儲在對象數組中?
[@] - one
[@] - two
[@] - three
或是存儲在數組元素的字符串對象?
[one][two][three]
謝謝。
編輯:對不起,我的幻想圖失敗慘敗。
字符串對象可以從未被直接存儲在數組中,或作爲任何其他變量。這是總是引用,即使在一個簡單的例子,如:
string x = "foo";
這裏的x
值是一個參考,而不是一個對象。表達式值永遠不是一個對象 - 它總是一個引用,一個值類型值或一個指針。
它們作爲參考在內部存儲。存儲字符串的副本,並且在使用該字符串的任何地方,都存在對相同存儲字符串的引用。 (這是許多原因,字符串是不可變;否則,一個字符串的修改一個實例將修改到處似乎)
所有基元類型都直接存儲到數組中,但所有其他對象或引用類型都存儲爲內存引用。對於不限於字符串的所有對象都是如此。
Jon Skeet很好地描述了實際的實現,但讓我們考慮一下爲什麼CLR將字符串直接存儲在數組中是無意義的。
第一個原因是將字符串直接存儲在數組中會損害性能。如果字符串直接存儲在數組中,那麼要訪問數組的元素1000,CLR必須遍歷數組中所有字符串的字節,直到到達元素1000,檢查字符串邊界的所有時間。由於字符串和任何其他引用類型都以引用的形式存儲在數組中,因此找到數組的右元素需要一次乘法,一次加法和一個指針後面的操作(此處指針的概念位於實現級別,而不是程序員可見的水平)。這產生更好的性能。
字符串不能合理存儲在數組中的第二個原因是C# arrays of reference type are covariant。比方說,字符串直接存儲與
string[] strings = new string[] {"one", "two", "three"};
然後生成的陣中,你施放此爲一個對象數組,這是合法的
object[] objs = (object[])strings;
編譯器應該如何生成代碼,藉此可能性考慮在內?一個將對象數組作爲參數的方法可以將一個字符串數組傳遞給它,所以CLR需要知道是否作爲對象數組,或字符串數組或其他類型的數組索引到數組中。不知何故,在運行時,每個數組必須用數組的類型聲明標記,並且每個數組訪問必須檢查類型聲明,然後根據數組類型以不同的方式遍歷數組。堅持使用引用是非常簡單的,它允許單個數組訪問的實現並提高引導的性能。
你現在有點過頭了,但我會保存下來。謝謝! – user943870
感謝您的糾正。我正在編輯過程中。我們相信Jon Skeet的 – user943870