LINQ Select Many - Modify flattened collection
我有一个名为Activity的类。此类包含圈数列表,并且每个圈数都有一组跟踪点。
活动—多个->圈数—多个->跟踪点。
每当我展开TracPoints集合时,都会得到所有TracPoints的列表。但是,当我修改那些原件时,它们当然不会被修改,因为它是一个副本。
在每圈的跟踪点列表中,是否有任何方法可以更改我对扁平跟踪点所做的任何更改?
只要tracpoint是一个结构,就不可能以任何合理的方式。
每当将结构变量或字段的值赋给另一个变量或字段时,都会复制其内容。同样,当它作为方法参数传递或从方法返回时,它的值会被复制。这是值语义[1]。将其与具有值语义的原子类型(如
1 2 3 4 5 6 | static function Change(int j) { j = 3; } static void Main(string[] args) { int i = 2; Change(i); System.Console.WriteLine(i); } |
如果执行selectmany,则集合中的每个值都可能被分配给某个临时局部变量,然后从迭代器(selectmany)返回,因此,在迭代器中输出值之前,它会被复制,实际上可能会被复制多次。所以您要更新的是结构的副本。像在示例中一样,您没有更改变量
这就是为什么结构应该是不可变的。不要在结构中具有getter和setter属性,它们应该只有getter。要更改结构的属性值,可以实现复制整个原始结构的方法、更改所需属性的值并返回新的结构实例。事实上,它的副本也会被退回。例子:
1 2 3 4 5 6 7 8 9 10 11 12 |
也就是说,可以用指针和不安全的C来实现您想要的,但是相信我,将您的结构改为类会更容易,这样它们就具有引用语义而不是值语义,或者保留它们的结构,但使它们不可变,不使用LINQ,而是使用旧的循环。如果您想在这种场景中对selectmany之类的东西使用linq,那么您可能不太关心结构和类之间的性能差异…
[1]http://msdn.microsoft.com/en-us/library/aa664472(v=vs.71).aspx