#835 – A Generic List Can Store Value-Typed or Reference-Typed Objects

You can use a generic list, defined by the List<T> class, to store a dynamically sized collection of objects.  A List<T> can store any type of object, including both value-typed and referenced-typed objects.

            // List of integers
            List<int> favNumbers = new List<int>();

            // List of Dog objects
            List<Dog> myDogs = new List<Dog>();
            myDogs.Add(new Dog("Kirby", 15));
            myDogs.Add(new Dog("Ruby", 3));

            // List of structs
            List<Point3D> points = new List<Point3D>();
            points.Add(new Point3D(1.0, 1.0, 0.5, "Here"));
            points.Add(new Point3D(2.0, 2.0, 0.5, "There"));



#834 – Use a Generic List to Store a Collection of Objects

You can use the List<T> class, defined in System.Collections.Generic, to store a list of objects that all have the same type.  This generic list is one of several collection classes that allow you to store a collection of objects and manipulate the objects in the collection.

You can think of a List<T> as an array that grows or shrinks in size as you add or remove elements.  You can easily add and remove objects to a List<T>, as well as iterate through all of its elements.

You can store a collection of either value-typed or reference-typed objects in a List<T>.

            // Define a list of integers
            List<int> favNumbers = new List<int>();

            // Add a couple numbers to the list

            // Iterate through the list to get each int value
            foreach (int i in favNumbers)

            // Remove 1st element (at position = 0)



#778 – A struct Isn’t Mutable When Used in a Collection

struct is normally mutable, i.e. you can modify the values of its members directly.

However, if a struct is used in a collection class, like a List<T>, you can’t modify its members.  Referencing the item by indexing into the collection returns a copy of the struct, which you can’t modify.  To change an item in the list, you need to create a new instance of the struct.

            List<DogCollarInfo> collarList = new List<DogCollarInfo>();

            // Create a few instances of struct and add to list
            collarList.Add(new DogCollarInfo(0.5, 14.0));
            collarList.Add(new DogCollarInfo(0.3, 12.0));

            // Compile-time error: Can't modify '...' because it's not a variable
            collarList[1].Length = 22.0;

            // Do this instead
            collarList[1] = new DogCollarInfo(collarList[1].Width, 22.0);

If you store the structs in an array, then you can change the value of one of the struct’s members.

            DogCollarInfo[] arr = new DogCollarInfo[2];
            arr[0] = new DogCollarInfo(0.5, 14.0);
            arr[0].Length = 5.0;  // OK

#423 – Compare Two Lists Using SequenceEquals

If you use either the == operator or the Equals method of the List<T> type to compare two lists, the return value will be true only if you are comparing two references to the exact same List<T> instance.  List<T> does not override either the == operator or the Equals method, so the comparison falls back to the reference equality check performed by Object.Equals.

            List<int> myPrimes = new List<int> { 2, 3, 5, 7, 11, 13, 17 };
            List<int> yourPrimes = new List<int> { 2, 3, 5, 7, 11, 13, 17 };

            // == and Equals : reference equality
            bool compare = (myPrimes == yourPrimes);        // false
            compare = myPrimes.Equals(yourPrimes);     // false

If you want to compare two lists by comparing the values of the objects in the list, you can use the SequenceEqual method provide by System.Linq.

            // SequenceEquals method : value equality
            compare = myPrimes.SequenceEqual(yourPrimes);  // true

            List<int> dougsPrimes = new List<int> { 2, 3, 5, 7, 11, 13, 19 };  // oops
            compare = yourPrimes.SequenceEqual(dougsPrimes);  // false