從這個Answer,我開始知道KeyValuePair是不可變的。如何確定.NET(BCL)類型是不可變的
我瀏覽了docs,但找不到有關不可變行爲的任何信息。
我想知道如何確定一個類型是不可變的嗎?
從這個Answer,我開始知道KeyValuePair是不可變的。如何確定.NET(BCL)類型是不可變的
我瀏覽了docs,但找不到有關不可變行爲的任何信息。
我想知道如何確定一個類型是不可變的嗎?
第一個跡象是概述中屬性的文檔顯示「獲取鍵/值對中的鍵」。 第二個更明確的指示,將是房產本身的描述:
屬性爲「只讀」的事實表明它「可能」是不可變的,但絕不意味着它實際上是。所有「只讀」意味着在這種情況下,不能使用屬性設置器來更改屬性的值。例如,'List
OP的問題是:「我無法在文檔中的任何位置找到KeyValuePair的Value屬性無法更改的地方。它絕對是有記錄的。其實很清楚。它說:「你不能給KeyValuePair.Value賦值」。如果這不是應該如何閱讀文檔,我建議扔掉90%的文檔。雖然我正式同意你的意見(也就是說,按照你的例子,「Count」也是一個屬性,但不能直接改變,這是一個派生屬性),我仍然堅持我的觀點,即文檔是絕對完全清楚OP的問題。 –
我不認爲你可以通過看的文檔找到不可改變的「證據」,但也有幾個強勢指標:
struct
(why does this matter?)對於確切的證據證明我建議下載BCL的reference source從微軟或使用IL反編譯器來告訴你一個類型會是什麼樣子的代碼。
A KeyValuePair<T1,T2>
是一個結構體,如果沒有Reflection,只能通過複製另一個包含所需值的KeyValuePair<T1,T2>
的內容在其構造函數外突變。需要注意的是該語句:
MyKeyValuePair = new KeyValuePair(1,2);
像結構中的所有類似的構造函數調用,實際上是通過創建的KeyValuePair<int,int>
一個新的臨時實例(本身執行構造函數之前發生),設置該實例的字段值(用做構造函數),將該新臨時實例的所有公共和私有字段複製到MyKeyValuePair
,然後丟棄該臨時實例。
考慮下面的代碼:
static KeyValuePair MyKeyValuePair; // Field in some class // Thread1 MyKeyValuePair = new KeyValuePair(1,1); // *** MyKeyValuePair = new KeyValuePair(2,2); // Thread2 st = MyKeyValuePair.ToString();
因爲MyKeyValuePair
恰恰是4個字節,在線程1第二個語句將同時更新這兩個字段。儘管如此,如果Thread1中的第二個語句在Thread2的評估MyKeyValuePair.Key.ToString()
和MyKeyValuePair.Value.ToString()
之間執行,則第二個ToString()
將對結構的新的突變值起作用,即使第一個已完成的ToString()
對突變之前的值進行操作。
所有非平凡的結構體,無論它們是如何聲明的,它們的字段都具有相同的不變性規則:可以改變結構的代碼可以改變它的字段;無法更改結構的代碼不能更改其字段。有些結構可能會迫使人們去改變其中的一個領域,但將結構類型設計爲「不可變」既不必要也不足以確保實例的不可變性。 「不可變的」結構類型有一些合理的用途,但是如果有什麼需要更多的關注比公開域公開的結構所需的更多的用例。
你的意思是編程確定? – ColWhi
否,來自文檔/反射器等 – Tilak