[c-sharp]view plain
copy
public
struct
aa
} public
class
test
} 我們假設有這樣的乙個結構體。因為結構體是值型別的,在沒有修飾的情況下,我們的方法中,傳入,傳出都是傳遞的值,每次傳遞都進行了一次值的拷貝。
所以,我們這樣操作是不可行的。
datas[1].value = 10;
為什麼呢,因為datas[1]不是第二個物件,而是第二個物件的副本,你修改副本,當然不會影響原本的值了。正確的寫法是這樣的
datas[1] = new aa(10);
這只是開始。可能有人會問,為什麼我用data[i]是這個元素的副本呢?我們來詳細的介紹一下。
首先,請先閱讀msdn以增加一些基礎的了解
struct(c# 參考)
結構(c# 程式設計指南)
如何:了解向方法傳遞結構和向方法傳遞類引用之間的區別(c# 程式設計指南)
了解過基礎,我們看看正題
[c-sharp]view plain
copy
void
foo(structvalue o){}
//沒有人懷疑這裡的o是個結構體物件的副本。對吧。這個還有疑問的複習msdn去。
structvalue foo()
這裡都明白,返回的f是定義的f的乙個副本,沒有問題吧。
看看list的索引器
[c-sharp]view plain
copy
public
t this
[int
index]
return
this
._items[index];
//這裡返回的是this._items[index]的副本,能理解了吧。
} [targetedpatchingoptout("performance critical to inline across ngen image boundaries"
)]
set
this
._items[index] = value;
//這裡是把你的value副本複製到索引器指定的位置
this
._version++;
} }
以上3個例子看懂。這個問題就清晰了。
貼的這3個**已經很明顯的告訴你這樣乙個原因:
data[1]是通過list的索引器訪問的值型別陣列中的某個元素,返回的是這個元素的副本。而設定也是副本設定,所以可以設定,可以讀取,不可以通過副本的修改影響到list中的值型別陣列。
為了進一步證明這一點,我來用乙個反射的例子來演示一下:
[c-sharp]view plain
copy
private
static
void
testchangestructlist()
結果:
原始list:12
使用list的索引器賦值12
反射list內部的值型別陣列賦值23
還沒看懂的,最後再講一次。
list[i]
這是叫做索引器的,索引器是一種屬性,屬性就是在呼叫方法,而值型別無法返回乙個引用,返回的是值,所以索引器返回的,是你新增進去變數的副本。而因為值型別無法傳遞引用,所以新增實際也是使用副本的方式新增的。所以對於值型別的list,索引器的結果,可以訪問,可以修改,但無法直接存回去,如何儲存?可以重新的賦值,例如
listpoints = new list();
points.add(new point());//0,0
修改呢,就整個重新複製
points[0] = new point(1,1);
你不能修改一項points[0].x = 1;
這樣不可以的。
希望這樣說,各位不明白的能明白。明白的更明白。
List中的值型別無法修改的原因詳解
c sharp view plain copy public struct aa public class test 我們假設有這樣的乙個結構體。因為結構體是值型別的,在沒有修飾的情況下,我們的方法中,傳入,傳出都是傳遞的值,每次傳遞都進行了一次值的拷貝。所以,我們這樣操作是不可行的。datas 1...
List中的值型別無法修改的原因詳解
public struct aa public class test 我們假設有這樣的乙個結構體。因為結構體是值型別的,在沒有修飾的情況下,我們的方法中,傳入,傳出都是傳遞的值,每次傳遞都進行了一次值的拷貝。所以,我們這樣操作是不可行的。datas 1 value 10 為什麼呢,因為datas 1...
python中改變list中list值的問題
l s 0,0,0 for i in range 3 l 1 1 1 print l 如上 定義乙個空list,新增元素也為list型別。本意是想改變list l中乙個值,使其結果為 0,0,0 0,1,0 0,0,0 但執行的結構下圖所示,將list l中的所有元素都改變了。為找到原因,檢視pyt...