我有一个名为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'吗? –
你可以把一些代码,请 –
_“当然,原件不会被修改,因为它是一个副本”_不一定是,但我们不能确定,直到我们看到代码在哪里你扁平化集合。 –