c# - linq查询的结果可以作为引用吗?

标签 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

或者当我添加新修饰符时上下文会发生变化?这种行为的原理是什么?

最佳答案

在我看来,您想找到其中 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/

相关文章:

c# - Entity Framework ,查询中未映射属性

c# - asp.net:如何将类似 LinkBut​​ton 的链接功能与表格单元格背景上的委托(delegate)连接起来?

c# - 如何将计时器添加到 C# 控制台应用程序

c# - 重复消除分配

非 PUBLIC 的 C# CreateDocumentType

c# - Json.NET解析对象中的数组

c# - 我可以使用 LINQ 从 List<String> 返回 List<Person>

.net - 用户定义的 linq 过滤器

linq - 选择联接+ linq联接中所有表的所有列

c# - 扩展方法语法与查询语法