Result of linq query can be used as reference?
In this scenario ( http://ideone.com/kxevv ):
using System;
using System.Linq;
using System.Collections.Generic;
public class Test{
public static void Main(){
开发者_StackOverflow社区 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;}
}
Is there some way to change ChangeVal
by reference? Or better, why the print result isn't 20, 24
?
Or when I put the new modifier the context change? What's the principle involved with this bahavior?
It looks to me like you want to find the index
of the item where p => p.A == "6"
, and then set 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
If you were just working with an IEnumerable
, however, this method would not be available. This is by design: the IEnumerable
interface doesn't give you any methods to change the data: you're only supposed to iterate across it. You could, however, create a projection that would produce the same result without actually modifying the list itself:
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
Concerning the principles that govern this, you definitely need to learn about the memory model used by .NET and Java. Unless you are using unsafe
code, objects are considered to be value-by-reference. This means that when you change the value of changeVal
via the =
operator, you are literally pointing the variable itself to a different location, rather than replacing or modifying the memory at the location it currently points to. Spending time really grokking the memory model will help you more in job interviews and in real life than just about anything else you can learn about .NET and Java.
精彩评论