LINQ - Where表达式是否返回对象实例的新实例或引用

Bra*_*don 39 .net c# linq

对于某些人来说,这可能是一个基本问题,但它会影响我设计一个程序的方式.

我有一个类型A的集合:

IEnumerable<A> myCollection;
Run Code Online (Sandbox Code Playgroud)

我按照两个不同的标准过滤我的收藏:

IEnumerable<A> subCollection1 = myCollection.Where(x => x.Count > 10);
etc.
Run Code Online (Sandbox Code Playgroud)

现在,我知道.Where表达式将返回IEnumerable的新实例,但新集合是否包含与'myCollection'引用的类型A实例相同的引用,或者是否创建了类型A的新副本?如果创建了类型为"A"的新实例,是否可以说"subCollection1"引用与"myCollection"引用相同的A实例?

编辑:添加进一步的说明.

我正在寻找一种方法,以便当我对'subCollection1'中的'A'实例进行更改时,它也会被修改为'myCollection'.

Alb*_*nbo 44

如果它们是类,则实例相同,但如果它们是结构/值类型则复制.

int,byte和double是值类型,结构(如System.Drawing.Point和自定义结构).但是字符串,你自己的所有类,基本上都是"其余的",都是引用类型.

注意:LINQ使用与所有其他分配相同的规则.

对象:

Person p1 = new Person();
p1.Name = "Mr Jones";
Person p2 = p1;
p2.Name = "Mr Anderssen";
// Now p1.Name is also "Mr Anderssen"
Run Code Online (Sandbox Code Playgroud)

对于结构:

Point p1 = new Point();
p1.x = 5;
Point p2 = p1;
p2.x = 10;
// p1.x is still 5
Run Code Online (Sandbox Code Playgroud)

使用LINQ时适用相同的规则.

  • @Richard:另外值得注意的是,匿名类型在C#中是不可变的,因此无论如何都无法修改匿名类型实例. (3认同)

rom*_*nlv 15

实际上这取决于收藏.在某些情况下,Linq方法可以返回克隆对象而不是对原始文件的引用,请看一下这个测试:

        [Test]
    public void Test_weird_linq()
    {
        var names = new[]{"Fred", "Roman"};
        var list = names.Select(x => new MyClass() { Name = x });

        list.First().Name = "Craig";
        Assert.AreEqual("Craig", list.First().Name);            
    }

    public class MyClass
    {
        public string Name { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

即使许多人认为在"list.First()"中将返回相同的对象,此测试也会失败,但如果您使用"使用ToList()修改的另一个集合,它将起作用"

var list = names.Select(x => new MyClass() { Name = x }).ToList();
Run Code Online (Sandbox Code Playgroud)

我不知道为什么它会以这种方式工作,但是在编写代码时要记住这一点:)

可以帮助理解LINQ如何在内部工作


And*_*rey 12

它们是相同的对象.Where只过滤,Select生成(可以产生)新实例.


Mat*_*eer 5

创建一个引用类型的新对象并非易事。LINQ 不知道该怎么做。处理引用类型时,LINQ 始终返回相同的实例。