LINQ - Does the Where expression return new instance or reference to object instance

后端 未结 5 1805
自闭症患者
自闭症患者 2021-01-31 15:01

This is probably a basic question for some, but it affects how I design a piece of my program.

I have a single collection of type A:

IEnumerable         


        
相关标签:
5条回答
  • 2021-01-31 15:14

    Making a new object that is a reference type is non-trivial. LINQ would have no idea how to do it. LINQ always returns the same instances when dealing with reference types.

    0 讨论(0)
  • 2021-01-31 15:16

    I just wanted to add to some of the other answers -- in general, when I'm not sure of something but require a particular behavior, I'll add a unit test for it. You could easily put this into a test and then check for equality, which will tell you if you're looking at a reference of the object in the original container. Some may argue that this is stupid because you "should just know" what happens, but for me I know I will either be 1) unsure because I'm not an awesome programmer, and 2) there are always nights where I have to burn the midnight oil, and it's good to have the reassurance that something behaves as you need it to.

    0 讨论(0)
  • 2021-01-31 15:17

    The instances are the same if they are classes, but copies if they are structs/value types.

    int, byte and double are value types, as are structs (like System.Drawing.Point and self-defined structs). But strings, all of your own classes, basically "the rest", are reference types.

    Note: LINQ uses the same rules as all other assignments.

    For objects:

    Person p1 = new Person();
    p1.Name = "Mr Jones";
    Person p2 = p1;
    p2.Name = "Mr Anderssen";
    // Now p1.Name is also "Mr Anderssen"
    

    For structs:

    Point p1 = new Point();
    p1.x = 5;
    Point p2 = p1;
    p2.x = 10;
    // p1.x is still 5
    

    The same rules apply when using LINQ.

    0 讨论(0)
  • 2021-01-31 15:31

    They are same objects. Where only filters, Select produces (can produce) new instances.

    0 讨论(0)
  • 2021-01-31 15:35

    Actually it depends on the collection. In some cases, LINQ methods can return cloned objects instead of references to originals. Take a look at this test:

    [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; }
    }
    

    This test will fail, even though many people believe that the same object will be returned by list.First(). It will work if you use another collection "modified with ToList()".

    var list = names.Select(x => new MyClass() { Name = x }).ToList();
    

    I don't know for sure why it works this way, but it's something to have in mind when you write your code :)

    This question can help you understand how LINQ works internally.

    0 讨论(0)
提交回复
热议问题