0

I am trying to learn how to use LINQ in C#. I don't want the source List to be changed but somehow it does get changed with this code. The program compiles and runs without errors (VS2019, W10,64). A breakpoint at the break statement shows that LinqList has been changed. Could someone please tell me where my error is? I have the source code available in a zip file. +

using System;
using System.Collections.Generic;
using System.Linq;

namespace LINQProblem
{
   class Program
    {
        public static List<MyTestClass> LinqList = new List<MyTestClass>();
        static void Main(string[] args)
        {
            // for loop to initialize LinqList
            for ( var i = 0; i < 10; i++ )
            {
                LinqList.Add(new MyTestClass());

                if (i % 2 != 0)
                {
                    LinqList[i].left = i * 10;
                    LinqList[i].isChecked = true;
                }
                else
                {
                    LinqList[i].left = (i + 200) * 10;
                }
                LinqList[i].right = LinqList[i].left + 5;
            }

            // filter LinqList and order by the smallest left
            var filteredData = LinqList 
                .Where(x => x.isChecked )
                .OrderBy(x => x.left ).ToList();

            for (;;)
            {
                filteredData[0].isChecked = false;

                // Re-filter  (more code here but not necessary to illustrate the problem)

                filteredData = filteredData 
                    .Where(x => x.isChecked)
                    .OrderBy(x => x.left).ToList();

                if (filteredData.Count == 0)
                {
                    // everything works to here but now values in LinqList have been changed
                    filteredData = LinqList
                        .Where(x => x.isChecked)
                        .OrderBy(x => x.left).ToList();
                    // filteredData.Count now equal zero because isChecked in LinqList has been changed to false
                    break;
                }
            }
            Console.WriteLine("\nPress any key to exit...");
            Console.ReadLine();
        }
    }
}

namespace LINQProblem
{
    class MyTestClass
    {
        public double left { get; set; }
        public double right { get; set; }
        public bool isChecked { get; set; }
    }
}
  • 3
    It's not the list that's changing its the objects in the list. When you do `filteredData[0].isChecked = false;` your changing the objects in `LinqList` because `filteredData` is just a list of references to objects in `LinqList`. – juharr Nov 10 '20 at 20:18
  • 1
    *LinqList has been changed* -- how? What is different? – Gert Arnold Nov 10 '20 at 20:41
  • You modify the contents of the list here: `filteredData[0].isChecked = false;`. Your list holds references to objects. It doesn't matter where you modify the values stored in those objects, they will appear changed however you look at the objects. The list isn't different, but the objects within have been modified. See duplicate for further discussion of how reference types work. – Peter Duniho Nov 11 '20 at 01:07
  • `if (filteredData.Count == 0) { // everything works to here...` Here, filteredData is empty, it doesn't contain any elements, otherwise you wouldn't be here. Later: `// filteredData.Count now equal zero because ...` no not because, it was already empty, otherwise you wouldn't be in the `if` – Harald Coppoolse Nov 16 '20 at 09:09

0 Answers0