我有一個名爲ACTIVITY的類。這個類包含一個圈數列表,每個圈都有一個TRACPOINTS集合。LINQ Select Many - 修改展平集合
ACTIVITY --many - > LAPS --- many - > TRACPOINTS。
每當我記錄TRACPOINTS集合時,我都會得到所有TRACPOINTS的列表。但是,當我修改那些當然原件不會被修改,因爲它是一個副本。
有沒有什麼辦法可以改變Tracpoints列表中每一圈的變化?
我有一個名爲ACTIVITY的類。這個類包含一個圈數列表,每個圈都有一個TRACPOINTS集合。LINQ Select Many - 修改展平集合
ACTIVITY --many - > LAPS --- many - > TRACPOINTS。
每當我記錄TRACPOINTS集合時,我都會得到所有TRACPOINTS的列表。但是,當我修改那些當然原件不會被修改,因爲它是一個副本。
有沒有什麼辦法可以改變Tracpoints列表中每一圈的變化?
只要TRACPOINT是一個結構體,就不可能以任何合理的方式。
只要將結構變量或字段的值賦給其他變量或字段,就會複製其內容。將它作爲方法參數傳遞或從方法返回它同樣適用,它的值將被複制。這是價值語義學[1]。將其與原子類型如int
進行比較,它們也具有值語義。你可能會想到下面的代碼打印2,沒有3
static function Change(int j) { j = 3; }
static void Main(string[] args) {
int i = 2;
Change(i);
System.Console.WriteLine(i);
}
如果你做的SelectMany,從收集的每個值可能分配到一些臨時局部變量,然後從迭代器(的SelectMany)返回,因此它被複制並且實際上可能被複制了很多次,然後才從迭代器中出來。所以你正在更新的是結構的副本。就像在這個例子中,你不會改變變量i
,但它的副本存儲在變量j
中。
這就是爲什麼結構體應該是不可變的。他們應該只有getter,而不是在你的結構中有getter和setter屬性。要更改結構的屬性值,可以實現複製整個原始結構的方法,更改所需屬性的值並返回新的結構實例。事實上,它的副本將會被返回。例如:
struct S {
int f;
public int F { get { return this.f; } }
public S SetF(int newVal) {
var s = new S();
s.f = newVal;
return s;
}
}
var x = new S();
x = x.SetF(30);
這就是說,它可能是可能達到你想要的指針和不安全的C#是什麼,但相信我,這將是比較容易的方式來改變你的結構上課,讓他們有參考的語義,而不是的價值語義,或保留它們的結構,但使它們不可變,不要使用Linq,而要使用舊式循環。如果你想在這樣的情況下使用Linq爲類似的SelectMany,你可能不關心結構和類這麼多之間的性能差異...
[1] http://msdn.microsoft.com/en-us/library/aa664472(v=vs.71).aspx
爲什麼? Tracpoint是'struct'嗎? –
你可以把一些代碼,請 –
_「當然,原件不會被修改,因爲它是一個副本」_不一定是,但我們不能確定,直到我們看到代碼在哪裏你扁平化集合。 –