在这种情况下( http://ideone.com/kxevv ):
using System;
using System.Linq;
using System.Collections.Generic;
public class Test{
public static void Main(){
List<Moo> list = new List<Moo>();
list.Add(new Moo {A = "5", B = "10"});
list.Add(new Moo {A = "6", B = "12"});
var changeRef = list.Where(p=>p.A == "5").First();
changeRef.B = "20";
var changeVal = list.Where(p=>p.A == "6").First();
changeVal = new Moo {A = "6", B = "24"};
Console.WriteLine(string.Join(", ", list.Select(p =>p.B).ToArray())); //prints 20, 12
}
}
public class Moo{
public string A {get;set;}
public string B {get;set;}
}
有没有办法通过引用更改ChangeVal
?或者更好的是,为什么打印结果不是 20, 24
?
或者当我添加新修饰符时上下文会发生变化?这种行为的原理是什么?
最佳答案
在我看来,您想找到其中 p => p.A == "6"
的项目的 index
,然后设置 list[索引] = new Moo{...};
var index = list.FindIndex(p=>p.A == "6");
list[index] = new Moo {A = "6", B = "24"};
Console.WriteLine(string.Join(", ", list.Select(p =>p.B).ToArray())); //prints 20, 24
但是,如果您只是使用 IEnumerable
,则此方法将不可用。这是设计使然:IEnumerable
接口(interface)不提供任何更改数据的方法:您只需要迭代它。但是,您可以创建一个投影来产生相同的结果,而无需实际修改列表本身:
var query = list.Select(p => p.A == "6" ? new Moo {A = "6", B = "24"} : p);
Console.WriteLine(string.Join(", ", list.Select(p =>p.B).ToArray())); //prints 20, 12
Console.WriteLine(string.Join(", ", query.Select(p =>p.B).ToArray())); //prints 20, 24
关于管理此问题的原则,您肯定需要了解 .NET 和 Java 使用的内存模型。除非您使用不安全
代码,否则对象将被视为按引用传递值。这意味着,当您通过 =
运算符更改 changeVal
的值时,实际上是将变量本身指向不同的位置,而不是替换或修改变量所在的内存。它当前指向的位置。花时间真正摸索内存模型将比您可以了解的有关 .NET 和 Java 的任何其他内容对您在工作面试和现实生活中更有帮助。
关于c# - linq查询的结果可以作为引用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7491003/