linq查询的结果可以作为参考吗?

时间:2011-09-20 19:54:31

标签: c# linq

在这种情况下(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

或者当我将新修饰符改为上下文时?这个行为涉及的原则是什么?

1 个答案:

答案 0 :(得分:5)

我认为您希望找到index项目的p => p.A == "6",然后设置list[index] = 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接口不会为您提供任何更改数据的方法:您只应迭代它。但是,您可以创建一个投影,该投影将产生相同的结果,而无需实际修改列表本身:

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使用的内存模型。除非您使用unsafe代码,否则对象被视为按引用值。这意味着当您通过changeVal运算符更改=的值时,您实际上将变量本身指向其他位置,而不是替换或修改当前指向的位置的内存。花时间真正了解内存模型将有助于您在求职面试和现实生活中获得更多,而不仅仅是您可以了解的有关.NET和Java的任何其他内容。