Introduction to List-Based Classes

Overview

To support the creation of any kinds of list, the .NET Framework provides a class named ArrayList. The .NET Framework provides a generic equivalent and improved class named List. The ArrayList class is defined in the System.Collections namespace while the generic List class is a member of the System.Collections.Generic namespace. The ArrayList class starts as follows:

public class ArrayList : IList,
                         ICollection,
             			 IEnumerable,
            			 ICloneable

The generic List<T> class starts as follows:

public class List<T> : IList<T>,
                       ICollection<T>,
                       IEnumerable<T>,
                       IList,
                       ICollection,
                       IEnumerable

Therefore, in order to use one of these classes in C# code, you can first include its namespace in the top section of the document. The ArrayList class implements the IList, the ICollection, and the IEnumerable interfaces. The List<> class implements the generic IList<>, the generic ICollection<>, the generic IEnumerable<>, the IList, the ICollection, and the IEnumerable interfaces.

You can use either the ArrayList or the generic List<> class to create and manage values for a list. To create an ArrayList collection, simply declare a variable of that class and initialize it. The default constructor of each class allows you to create an empty list before adding values to it. Here is an example of starting an ArrayList collection:

using System.Collections;

public class Exercise
{
    public static int Main()
    {
        ArrayList molecules = new ArrayList();

        return 10_000;
    }
}

To create a List<> collection, declare and initialize a variable to that class. Like any normal (non-static) class, to use a List object, you must first declare a variable for it. You must specify the parameter type between < and >. The formula to declare the variable is:

List<type-name> variable-name = new List<type-name>();

The parameter type can be a primitive type. Here are examples:

using System.Collections.Generic;

public class Exercise
{
    public static int Main(string[] args)
    {
        List<int> temperatures = new List<int>();
        List<double> distances = new List<double>();
        List<string> states = new List<string>();

        return 11_220;
    }
}

You can also declare the variable using the var keyword:

var variable-name = new List<type-name>();

You can also use the dynamic keyword:

dynamic variable-name = new List<type-name>();

Here are examples:

using System;
using System.Collections.Generic;

public class Exercise
{
    public static int Main(string[¸args)
    {
        List<int> numbers = new List<int>();

        var symbols = new List<char>();
        dynamic names = new List<string>();

        return 0;
    }
}

A parameter type can be a class type. You can use one of the existing classes of the .NET Framework. Here are examples:

using System;
using System.Collections.Generic;

public class Exercise
{
    public static int Main()
    {
        List<EventArgs> eventArguments = new List<EventArgs>();
        var enumerations = new List<Enum>();
        dynamic exceptions = new List<Exception>();

        return 0;
    }
}

If none of the .NET Framework built-in classes suits your needs, you can create your own class and specify it as the parameter type. Here is an example:

using System.Collections.Generic;

class Employee
{
}

public class Exercise
{
    public static int Main(string[] args)
    {
        List<Employee> employees = new List<Employee>();

        return 200;
    }
}

If you already have an ICollection-based list, that is, a list created from a class that implements the ICollection interface, you can initialize your ArrayList collection with it. To support this, the ArrayList class is equipped with the following constructor:

public ArrayList (System.Collections.ICollection c);

If you alaready have a collection created from an IEnumerable<> object, that is, a class that implements this interface, you can use it to start a List<> collection. To support this, the List<> class is equipped with a constructor that uses the following syntax:

public List (IEnumerable<T> collection);

A Read-Only List

A collection is said to be read-only if it doesn't allow the addition of items. To let you produce a read-only collection, the ArrayList provides an overloaded method named ReadOnly. The syntaxes of the two versions are:

public static ArrayList ReadOnly(ArrayList list)
public static IList ReadOnly(IList list)

Some operations cannot be performed on a read-only list. To perform such operations, you can first find out whether an ArrayList list is read-only. This is done by checking its IsReadOnly property.

Adding Values or Objects to a Collection

Adding an Item

The primary operation performed on a list is to add a value or an object to it. To support this, both the ArrayList and the List<> classes are equipped with a method named Add. The syntax of the System.Collections.ArrayList.Add() method is:

public virtual int Add(object value);

The argument of the method is the value or object to add to the collection. If the method succeeds with the addition, it returns the position where the value or object was added in the list. Here are example for an ArrayList variable:

using System.Collections;

public class Exercise
{
    public static void Main(string[] args)
    {
        System.Collections.ArrayList molecules = new System.Collections.ArrayList();

        molecules.Add("Ozone");
        molecules.Add("Oxygen");
        molecules.Add("Helium");
        molecules.Add("Sulfuric Acid");
        molecules.Add("Carbon Dioxide");
    }
}

The syntax of the System.Collections.Generic.List<>.Add() method is:

public void Add(T value);

If you are using a class, you must follow the rules of classes:

If the method fails to add the value and if you are using an ArrayList class, the compiler would throw an exception. The error could result from the list being read-only or being full.

Returning a Generic List From a Method

You can create a list in a method and return it. When defining the method, specify its return value as List<>. Inside the <> operator, write the type of value. Here is an example:

using System;
using System.Collections.Generic;

public class Exercise
{
    List<int> GetNumbers()
    {
        
    }
}

You can then define the method however you like, before exiting, you must make sure you return a List<> object. To use the list produced by the method, you can assign its return value to a local variable. Here is an example:

using System;
using System.Collections.Generic;

public class Exercise
{
    static List<int> GetNumbers()
    {
        List<int> nbrs = new List<int>();

        nbrs.Add(84);
        nbrs.Add(27407);
        nbrs.Add(5948);
        nbrs.Add(7);
        nbrs.Add(927482);

        return nbrs;
    }

    public static int Main(string[] args)
    {
        List<int> numbers = new List<int>();
        numbers = GetNumbers();

        return 0;
    }
}

Passing a Generic List as Argument

You can use a list either in a local method where it is created or you can pass it to be processed by another method. You pass it the same way you would any value, using List<type-of-value> argument-name. Here is an example:

using System.Collections.Generic;

public class Exercise
{
    void ShowNumbers(List<int> numbers)
    {
    }
}

In the method, you can use the argument any way you like.

Adding a Range of Items

Instead of adding one value at a time, you can first create a list of values and add that whole list at once. To support this operation, both the ArrayList and the List classes are equipped with a method named AddRange.

The syntax of the ArrayList.AddRange() method is:

public virtual void AddRange(ICollection collection);

The syntax of the List<>.AddRange() method is:

public void AddRange(IEnumerable<T> collection);

The ArrayList.AddRange() method takes as argument a list created from a class that implements the ICollection interface. The List<>.AddRange() method takes as argument a list created from a class that implements the generic IEnumerable<> interface. Here is an example:

using System.Collections.Generic;

public class Exercise
{
    public void Create
    {
        List<TimeSheet> timeSheets = new List<TimeSheet>();
        
        List<TimeSheet> totalWork = new List<TimeSheet>();

        totalWork.Add(new TimeSheet() { TimeSheetNumber = 100001, EmployeeNumber = "606384", StartDate = new DateTime(2018, 1, 1), Week1Monday = 0, Week1Tuesday = 0, Week1Wednesday = 0.00, Week1Thursday = 0.00, Week1Friday = 0.00, Week1Saturday = 8, Week1Sunday = 8, Week2Monday = 0.00, Week2Tuesday = 0, Week2Wednesday = 0.00, Week2Thursday = 0, Week2Friday = 0, Week2Saturday = 8, Week2Sunday = 8.00 });
        totalWork.Add(new TimeSheet() { TimeSheetNumber = 100002, EmployeeNumber = "952748", StartDate = new DateTime(2018, 1, 1), Week1Monday = 8, Week1Tuesday = 8, Week1Wednesday = 8.00, Week1Thursday = 8.00, Week1Friday = 8.00, Week1Saturday = 0, Week1Sunday = 0, Week2Monday = 8.00, Week2Tuesday = 8, Week2Wednesday = 8.00, Week2Thursday = 8, Week2Friday = 8, Week2Saturday = 0, Week2Sunday = 0.00 });
        totalWork.Add(new TimeSheet() { TimeSheetNumber = 100003, EmployeeNumber = "941148", StartDate = new DateTime(2018, 1, 1), Week1Monday = 9, Week1Tuesday = 10, Week1Wednesday = 8.50, Week1Thursday = 9.50, Week1Friday = 10.50, Week1Saturday = 12, Week1Sunday = 12, Week2Monday = 8.50, Week2Tuesday = 9, Week2Wednesday = 9.50, Week2Thursday = 8, Week2Friday = 10, Week2Saturday = 10, Week2Sunday = 8.50 });
        totalWork.Add(new TimeSheet() { TimeSheetNumber = 100004, EmployeeNumber = "927048", StartDate = new DateTime(2018, 1, 1), Week1Monday = 8, Week1Tuesday = 8, Week1Wednesday = 8.00, Week1Thursday = 8.00, Week1Friday = 8.00, Week1Saturday = 0, Week1Sunday = 0, Week2Monday = 8.00, Week2Tuesday = 8, Week2Wednesday = 8.00, Week2Thursday = 8, Week2Friday = 8, Week2Saturday = 0, Week2Sunday = 0.00 });

        timeSheets.AddRange(totalWork);
    }
}

Getting a Value or Object from a Collection

The Capacity of a List

After declaring an ArrayList or a List<T> variable, it is empty. As objects are added to it, the list grows. The list can grow tremendously as you wish. The number of items in the list is managed through the memory it occupies and this memory grows as needed. The number of items that the memory allocated is currently using is represented by a property named Capacity:

ArrayList: public virtual int Capacity { get; set; }
List<T>:   public int Capacity { get; set; }

The capacity of a list will usually be the least of your concerns. If for some reason you want to intervene and control the number of items that your list can contain, you can manipulate the Capacity property. For example, you can assign it a constant to set the maximum value that the list can contain. Instead of specifying the capacity after the list has been created, when declaring the list variable, you can specify its maximum capacity. To support this, both the ArrayList and the List<> classes are equipped with an additional constructor as follows:

public ArrayList(int capacity);
public List(int capacity);

You will hardly have any reason to use the Capacity property:

The Number of Items in a Collection

To provide the number of items in a collection, both the ArrayList and the List<> classes are equipped with a property named Count, which is an integer.

Here are examples of accessing it:

using System;
using System.Collections.Generic;

public class Exercise
{
    public static int Main()
    {
        List<Employee> contractors = new List<Employee>();

        Employee empl = new Employee(397947, "David", "Redson", 18.75);
        contractors.Add(empl);
        empl = new Employee(840004, "Simao");
        contractors.Add(empl);
        contractors.Add(new Employee());
        
        var seasonals = new List<Employee>();
        seasonals.Add(new Employee(848024, "Alima", "Bieyrou", 14.05));
        seasonals.Add(new Employee(fName : "Robert", lName : "Nants"));

        dynamic identifications = new List<Employee>();
        identifications.Add(new Employee(222222));

        Console.WriteLine("This company has {0} contractors, {1} seasonal " +
                          "employees, and {2} other type.", contractors.Count,
                          seasonals.Count, identifications.Count);
                          
        return 0;
    }
}

This would produce:

This company has 3 contractors, 2 seasonal employees, and 1 other type.
Press any key to continue . . .

The Capacity and the Count properties have this in common: the value of each increases as the list grows and the same value decreases if the list shrinks. On the other hand, Capacity is a read/write property. This means that you can assign a value to the capacity to fix the number of items that the list can contain. You can also get the value of the Capacity. The Count property is read-only because the counting of the current number of items is performed without your intervention.

Getting a Value or Object from a Collection

Getting to an Item Using an Indexer

To give you access to each member of their list, both the ArrayList and the List<> classes are equipped with a default property named Item. The Item property is an indexer. The first value of the list has an index of 0. The second has an index of 1, and so on.

To get a single value based on its position, you can apply the square brackets of arrays to the variable. Here is an example:

using static System.Console;
using System.Collections;

public class Exercise
{
    public static int Main(string[] args)
    {
        ArrayList molecules = new ArrayList();

        molecules.Add("Ozone");
        molecules.Add("Oxygen");
        molecules.Add("Helium");
        molecules.Add("Sulfuric Acid");
        molecules.Add("Carbon Dioxide");

        WriteLine("Molecule: {0}", molecules[1]);

        WriteLine("=====================================");
        return 50;
    }
}

This would produce:

Molecule: Oxygen
=====================================
Press any key to continue . . .

To let you access an item, the List<> class uses an indexed property named Item. This allows you to access its items using the [] operator. Here are examples:

using System;
using System.Collections.Generic;

public class Exercise
{
    public static int Main()
    {
        var name = new List<char>();
        name.Add('A');
        name.Add('p');
        name.Add('l');
        name.Add('e');

        Console.Write("{0}", name[0]);
        Console.Write("{0}", name[1]);
        Console.Write("{0}", name[1]);
        Console.Write("{0}", name[2]);
        Console.Write("{0}", name[3]);
        Console.WriteLine();

        return 0;
    }
}

This would produce:

Apple
Press any key to continue . . .

You can also use a for loop to access each item of the list. Here is an example:

using System;
using System.Collections.Generic;

public class Exercise
{
    public static int Main()
    {
        var internetCode = new List<char>();
        internetCode.Add('c');
        internetCode.Add('o');
        internetCode.Add('m');

        Console.Write("http://www.kamerun.");
        for(int i = 0; i < internetCode.Count; i++)
            Console.Write("{0}", internetCode[i]);

        Console.WriteLine();
        return 0;
    }
}

This would produce:

http://www.kamerun.com
Press any key to continue . . .

If the list is made of objects of a class, to access an item, apply the square brackets to the variable, followed by a period, and followed by the desired member of the class. Here are examples:

public class Exercise
{
    public static int Main()
    {
        List<Employee> contractors = new List<Employee>();

        Employee empl = new Employee(397947, "David", "Redson", 18.75);
        contractors.Add(empl);
        contractors.Add(new Employee(174966, "Alfred", "Swanson", 12.94));
        empl = new Employee(840004, "Simao");
        contractors.Add(empl);
        contractors.Add(new Employee(848024, "Alima", "Bieyrou", 14.05));
        contractors.Add(new Employee(number: 397462,
        			     fName : "Robert", 
        			     lName : "Nants"));

        dynamic identifications = new List<Employee>();
        identifications.Add(new Employee(222222));

        for (int i = 0; i < contractors.Count; i++)
        {
            Console.WriteLine("Employee #:    {0}\nFirst Name:    {1}\n" +
                              "Last Name:     {2}\n" +
                              "Hourly Salary: {3:F}",
                              contractors[i].EmployeeNumber,
                              contractors[i].FirstName,
                              contractors[i].LastName,
                              contractors[i].HourlySalary);
            Console.WriteLine("-----------------------");
        }
                          
        return 0;
    }
}

This would produce:

Employee #:    397947
First Name:    David
Last Name:     Redson
Hourly Salary: 18.75
-----------------------
Employee #:    174966
First Name:    Alfred
Last Name:     Swanson
Hourly Salary: 12.94
-----------------------
Employee #:    840004
First Name:    Simao
Last Name:     Doe
Hourly Salary: 12.00
-----------------------
Employee #:    848024
First Name:    Alima
Last Name:     Bieyrou
Hourly Salary: 14.05
-----------------------
Employee #:    397462
First Name:    Robert
Last Name:     Nants
Hourly Salary: 12.00
-----------------------
Press any key to continue . . .

Based on this, you can use a loop (while, do...while, or for) to visit each item through its index.

An issue to keep in mind is that the ArrayList[] indexer returns an Object value. Therefore, you may have to cast this value to your type of value to get it right.

Iterating Through a Collection

Besides using the index to access a value from the list, the ArrayList and the List<> classes implement the IEnumerable.GetEnumerator() method. For this reason, you can use the foreach loop to access each member of the collection. Here is an example:

using static System.Console;
using System.Collections;

public class Exercise
{
    public static int Main(string[] args)
    {
        Title = "Chemistry";
        ArrayList molecules = new ArrayList();

        molecules.Add("Ozone");
        molecules.Add("Oxygen");
        molecules.Add("Helium");
        molecules.Add("Sulfuric Acid");
        molecules.Add("Carbon Dioxide");

        WriteLine("Chemistry");
        WriteLine("-------------------------");
        foreach (string molecule in molecules)
            WriteLine("Molecule: {0}", molecule);

        WriteLine("=====================================");
        return 50;
    }
}

This would produce:

Chemistry
-------------------------
Molecule: Ozone
Molecule: Oxygen
Molecule: Helium
Molecule: Sulfuric Acid
Molecule: Carbon Dioxide
=====================================
Press any key to continue . . .

You can use the Item property to change a value in the list. Because the Item property is used to access an existing value from the list, the value must have been created. If you try setting the value of a non-existing item, the compiler would throw an ArgumentOutOfRangeException Exception.

In previous sections, we saw that you can use a for loop to scan a list of items. To support the foreach operator, the List<> class is equipped with a method named GetEnumerator. Its syntax is:

public List<(Of <(<'T>)>)>..::..Enumerator GetEnumerator();

Normally, you don't need to know anything about this method. You use foreach the same was we saw for arrays. Here is an example:

public class Exercise
{
    public static int Main()
    {
        List<Employee> employees = new List<Employee>();

        Employee empl = new Employee(397947, "David", "Redson", 18.75);
        employees.Add(empl);
        employees.Add(new Employee(174966, "Alfred", "Swanson", 12.94));
        employees.Add(new Employee(848024, "Alima", "Bieyrou", 14.05));
        employees.Add(new Employee(number: 397462, fName: "Robert",
                                     lName: "Nants", salary: 22.15));

        foreach (Employee staffMember in employees)
        {
            Console.WriteLine("================================");
            Console.WriteLine("Employee Record");
            Console.WriteLine("--------------------------------");
            Console.WriteLine("Employee #:    {0}", staffMember.EmployeeNumber);
            Console.WriteLine("First Name:    {0}", staffMember.FirstName);
            Console.WriteLine("Last Name:     {0}", staffMember.LastName);
            Console.WriteLine("Hourly Salary: {0}", staffMember.HourlySalary);
        }

        return 0;
    }
}

Taking Action For Each Value or Object

To provide you a faster means of accessing each item in a collection, the List<> class is equipped with a method named ForEach. Its syntax is:

public void ForEach(Action<T> action);

This method takes an Action delegate as argument. You can create a function and pass it as argument to the List<>.ForEach() method. Here is an example:

using static System.Console;
using System.Collections.Generic;

public class Exercise
{
    static void ShowEmployee(Employee empl)
    {
        WriteLine("================================");
        WriteLine("Employee Record");
        WriteLine("--------------------------------");
        WriteLine("Employee #:    {0}", empl.EmployeeNumber);
        WriteLine("First Name:    {0}", empl.FirstName);
        WriteLine("Last Name:     {0}", empl.LastName);
        WriteLine("Hourly Salary: {0}", empl.HourlySalary);
    }

    public static int Main(string[] args)
    {
        Title = "Chemistry";
        List<Employee> employees = new List<Employee>();

        Employee empl = new Employee(397947, "David", "Redson", 18.75);
        employees.Add(empl);
        employees.Add(new Employee(174966, "Alfred", "Swanson", 12.94));
        employees.Add(new Employee(848024, "Alima", "Bieyrou", 14.05));
        employees.Add(new Employee(number: 397462, fName: "Robert",
                                   lName: "Nants", salary: 22.15));

        employees.ForEach(ShowEmployee);

        WriteLine("=====================================");
        return 50;
    }
}

class Employee
{
    public long   EmployeeNumber { get; set; }
    public string FirstName      { get; set; }
    public string LastName       { get; set; }
    public double HourlySalary   { get; set; }

    public Employee(long number = 0, string fName = "John",
                    string lName = "Doe", double salary = 12.05D)
    {
        EmployeeNumber = number;
        FirstName = fName;
        LastName = lName;
        HourlySalary = salary;
    }

    public override string ToString()
    {
        base.ToString();

        return string.Format("================================\n" +
                             "Employee Record\n" +
                             "--------------------------------\n" +
                             "Employee #:    {0}\nFirst Name:    {1}\n" +
                             "Last Name:     {2}\nHourly Salary: {3}",
                             EmployeeNumber, FirstName,
                             LastName, HourlySalary);
    }
}

This method expects a function that defines what to do every time the compiler visits a members of the list. You do this by creating a method to do something on each member of the List<> collection and then pass that method to ForEach(). Here is an example:

of calling this method:

using static System.Console;
using System.Collections.Generic;

public class Exercise
{
    public static int Main(string[] args)
    {
        Title = "Chemistry";
        List<string> molecules = new List<string>();

        molecules.Add("Ozone");
        molecules.Add("Oxygen");
        molecules.Add("Helium");
        molecules.Add("Sulfuric Acid");
        molecules.Add("Carbon Dioxide");

        WriteLine("Chemistry");
        WriteLine("-------------------------");
        molecules.ForEach(str => {
            WriteLine("Molecule: {0}", str);
        });    

        WriteLine("=====================================");
        return 50;
    }
}

Checking Whether a List Contains an Item

Instead of the square brackets that allow you to retrieve a value based on its position, you can look for a value based on its complete definition. You have various options. You can first "build" an item and ask the compiler to check whether any item in the list matches your definition. To perform this search, depending on your class, you can call either the ArrayList.Contains() or the List<>.Contains() method. The syntax of the System.Collections.ArrayList.Contains() method is:

public virtual bool Contains(object value);

The syntax of the System.Collections.Generic.List<>.Contains() method is:

public bool Contains(T value);

The value to look for is passed as argument to the method. The compiler would look for the value or object, using the value type or the object definition. If the argument corresponds to an existing value or object, the method returns true. If the value or object is not found, the method returns false. Here is an example:

using System;
using System.Collections.Generic;

public class Exercise
{
    public static int Main()
    {
        var connection = new List<char>();
        connection.Add('c');
        connection.Add('o');
        connection.Add('n');
        connection.Add('n');
        connection.Add('e');
        connection.Add('c');
        connection.Add('t');
        connection.Add('i');
        connection.Add('o');
        connection.Add('n');

        for (int i = 0; i < connection.Count; i++)
            Console.Write("{0}", connection[i]);
        Console.WriteLine();

        if (connection.Contains('e'))
            Console.WriteLine("The list contains 'e'");
        else
            Console.WriteLine("There is no 'e' in the list");

        if (connection.Contains('g'))
            Console.WriteLine("The list contains 'g'");
        else
            Console.WriteLine("There is no 'g' in the list");

        return 0;
    }
}

This would produce:

connection
The list contains 'e'
There is no 'g' in the list
Press any key to continue . . .

This works because each structure of a primitive type is equipped to compare two of its values. The comparison would not work directly if the list is made of values of your own class. Consider the following:

using System;
using System.Collections.Generic;

public class Employee
{
    public long EmployeeNumber { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public double HourlySalary { get; set; }

    public Employee(long number = 0, string fName = "John",
                    string lName = "Doe", double salary = 12.05D)
    {
        EmployeeNumber = number;
        FirstName = fName;
        LastName = lName;
        HourlySalary = salary;
    }

    public override string ToString()
    {
        base.ToString();

        return string.Format("================================\n" +
                             "Employee Record\n" +
                             "--------------------------------\n" +
                             "Employee #:    {0}\nFirst Name:    {1}\n" +
                             "Last Name:     {2}\nHourly Salary: {3}",
                             EmployeeNumber, FirstName,
                             LastName, HourlySalary);
    }
}

public class Exercise
{
    public static int Main()
    {
        List<Employee> employees = new List<Employee>();

        Employee empl = new Employee(397947, "David", "Redson", 18.75);
        employees.Add(empl);
        employees.Add(new Employee(174966, "Alfred", "Swanson", 12.94));
        employees.Add(new Employee(848024, "Alima", "Bieyrou", 14.05));
        employees.Add(new Employee(number: 397462, fName: "Robert",
                                     lName: "Nants", salary: 22.15));

        Employee member = new Employee(174966, "Alfred", "Swanson", 12.94);

        bool exists = employees.Contains(member);

        if (exists == true)
            Console.WriteLine("The list contains the employee");
        else
            Console.WriteLine("No record of that employee was found");

        return 0;
    }
}

This would produce:

No record of that employee was found
Press any key to continue . . .

Notice that the compiler was not able to find the item even though it actually exists in the list. To make this method work on your class, you must override the Equals() method. Here is an example:

using System;
using System.Collections.Generic;

public class Employee
{
    public long EmployeeNumber { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public double HourlySalary { get; set; }

    public Employee(long number = 0, string fName = "John",
                    string lName = "Doe", double salary = 12.05D)
    {
        EmployeeNumber = number;
        FirstName = fName;
        LastName = lName;
        HourlySalary = salary;
    }

    public override bool Equals(object obj)
    {
        Employee e = (Employee)obj;

        if ((e.EmployeeNumber == this.EmployeeNumber) &&
            (e.FirstName == this.FirstName) &&
            (e.LastName == this.LastName) &&
            (e.HourlySalary == this.HourlySalary))
            return true;
        else
            return false;
    }

    public override string ToString()
    {
        base.ToString();

        return string.Format("================================\n" +
                             "Employee Record\n" +
                             "--------------------------------\n" +
                             "Employee #:    {0}\nFirst Name:    {1}\n" +
                             "Last Name:     {2}\nHourly Salary: {3}",
                             EmployeeNumber, FirstName,
                             LastName, HourlySalary);
    }
}

public class Exercise
{
    public static int Main()
    {
        . . . No Change

        return 0;
    }
}

This time, the program would produce:

The list contains the employee
Press any key to continue . . .

Searching for an Item

Another option to look for an item in a list consists of calling a method named BinarySearch supported by both the ArrayList and the List class. It is overloaded in three versions and one of them uses the following syntax:

public virtual int BinarySearch(object value);
public int BinarySearch(T value);

The value to look for is passed as argument to the method. Here is an example:

private void btnResult_Click(object sender, EventArgs e)
{
    string strFind = txtFind.Text;

    if( lstNames.BinarySearch(strFind) > 0 )
        txtResult.Text = "Found";
    else
        txtResult.Text = "Not Found";
}

Checking the Existence of an Item

To let you check whether a certain item exists in a collection, the list classes contain a method named Exists. The syntax for the List<> class is:

public bool Exists(Predicate<T> match);

This method takes a delegate as argument. Here is an example

using static System.Console;
using System.Collections.Generic;

public class Exercise
{
    public static int Main(string[] args)
    {
        Title = "Human Resources";
        List<Employee> employees = new List<Employee>();

        Employee empl = new Employee(397947, "David", "Redson", 18.75);
        employees.Add(empl);
        employees.Add(new Employee(174966, "Alfred", "Swanson", 12.94));
        employees.Add(new Employee(848024, "Alima", "Bieyrou", 14.05));
        employees.Add(new Employee(number: 397462, fName: "Robert",
                                   lName: "Nants", salary: 22.15));

        Employee staff = new Employee(928059);
        
        bool exists = employees.Exists((Employee member) =>            
        {
            return member.EmployeeNumber == staff.EmployeeNumber;    
        });
        
        if (exists == true)
            WriteLine("The list contains an employee with an employee number as {0}.", staff.EmployeeNumber);    
        else
            WriteLine("Our collection doesn't have an employee with an employee number of {0}.", staff.EmployeeNumber);

        WriteLine("--------------------------------------------------------------------------");

        staff = new Employee(848024);

        exists = employees.Exists((Employee member) =>
        {
            return member.EmployeeNumber == staff.EmployeeNumber;
        });

        if (exists == true)
            WriteLine("The list contains an employee with an employee number as {0}.", staff.EmployeeNumber);
        else
            WriteLine("Our collection doesn't have an employee with an employee number of {0}.", staff.EmployeeNumber);

        WriteLine("==========================================================================");
        return 50;
    }
}

class Employee
{
    public long   EmployeeNumber { get; set; }
    public string FirstName      { get; set; }
    public string LastName       { get; set; }
    public double HourlySalary   { get; set; }

    public Employee(long number = 0, string fName = "John",
                    string lName = "Doe", double salary = 12.05D)
    {
        EmployeeNumber = number;
        FirstName = fName;
        LastName = lName;
        HourlySalary = salary;
    }

    public override string ToString()
    {
        base.ToString();

        return string.Format("================================\n" +
                             "Employee Record\n" +
                             "--------------------------------\n" +
                             "Employee #:    {0}\nFirst Name:    {1}\n" +
                             "Last Name:     {2}\nHourly Salary: {3}",
                             EmployeeNumber, FirstName,
                             LastName, HourlySalary);
    }
}

This would produce:

Our collection doesn't have an employee with an employee number of 928059.
--------------------------------------------------------------------------
The list contains an employee with an employee number as 848024.
==========================================================================
Press any key to continue . . .

Finding a Value or Object in a Collection

To let you find an item in a collection, the List class is equipped with a method named Find. Its syntax is:

public T Find(Predicate<T> match);

This method takes a delegate as argument.

Removing a Value or Object from a Collection

Deleting an Item Using its Index

There are various ways you can remove an item from a list. To let you delete an item based on its index, the List<> class is equipped with a method named RemoveAt(). Its syntax is:

public void RemoveAt(int index);

When calling this method, pass the index of the undesired item. Here is an example:

using System;
using System.Collections.Generic;

public class Exercise
{
    public static int Main()
    {
        var internetCode = new List<char>();
        internetCode.Add('c');
        internetCode.Add('o');
        internetCode.Add('m');

        Console.Write("http://www.experiun.");
        for(int i = 0; i < internetCode.Count; i++)
            Console.Write("{0}", internetCode[i]);
        Console.WriteLine();

        internetCode.RemoveAt(1);

        Console.Write("http://www.experiun.");

        for (int i = 0; i < internetCode.Count; i++)
            Console.Write("{0}", internetCode[i]);
        Console.WriteLine();

        return 0;
    }
}

This would produce:

http://www.experiun.com
http://www.experiun.cm
Press any key to continue . . .

As you can see, the RemoveAt() method is the easy way to delete an item from a list if you know its index. Another way you can proceed would consist of finding out first if the item exists in the list, get its index, and then pass that index.

If the position is not valid because either it is lower or higher than the current Count, the compiler would throw an ArgumentOutOfRangeException exception.

Deleting a Range of Items

Still using an index, but instead of deleting just one, you can remove a range of value from a list. To support this, the List<> class provides the RemoveRange() method. Its syntax is:

public void RemoveRange(int index, int count);

The first item is the index from where to start deleting items. The second argument specifies the number of items to delete from the index to the end of the list.

Deleting a Known Item

Instead of locating an item based on its index, you can ask the List<> class to look for it. To support this, the class is equipped with a method named Remove. Its syntax is:

public bool Remove(T item);

In this case, you pass a definition of the item to the method. Here is an example:

using System;
using System.Collections.Generic;

public class Exercise
{
    public static int Main()
    {
        var internetCode = new List<char>();

        internetCode.Add('c');
        internetCode.Add('o');
        internetCode.Add('m');

        Console.Write("http://www.kariun.");

        for(int i = 0; i < internetCode.Count; i++)
            Console.Write("{0}", internetCode[i]);
        Console.WriteLine();

        internetCode.Remove('o');

        Console.Write("http://www.kariun.");

        for (int i = 0; i < internetCode.Count; i++)
            Console.Write("{0}", internetCode[i]);
        Console.WriteLine();

        return 0;
    }
}

When you call the List<>.Remove() method, the compiler would look for the item in the collection:

Notice that the list contains three Ns but only the first was removed.

If the item is based on a class, you must (it is your responsibility, the List class it not equipped to) provide a way to identify an item. This is usually done by overriding the Equals() method.

Clearing a List

To remove all items from a list at once, you can call the Clear() method of either the ArrayList or the List<> class. The syntax for the List<> class is:

Here is an example of calling the ArrayList.Clear() method:

using System.Collections;
using static System.Console;

public class Exercise
{
    public static int Main(string[] args)
    {
        Title = "Chemistry";
        ArrayList molecules = new ArrayList();

        molecules.Add("Ozone");
        molecules.Add("Oxygen");
        molecules.Add("Helium");
        molecules.Add("Sulfuric Acid");
        molecules.Add("Carbon Dioxide");

        WriteLine("Original List");
        WriteLine("-----------------------------------");

        if (molecules.Count > 0)
        {
            foreach (string molecule in molecules)
            {
                WriteLine(string.Format("Molecule: {0}", molecule));
            }
        }
        else
        {
            WriteLine("There is no molecule to show.");
        }

        WriteLine("-----------------------------------");

        molecules.Clear();

        WriteLine("After clearing the list ...");

        if (molecules.Count > 0)
            foreach (string molecule in molecules)
                WriteLine("Molecule: {molecule}");
        else
            WriteLine("There is no molecule to show.");

        WriteLine("===================================");
        return 22622;
    }
}

This would produce:

Original List
-----------------------------------
Molecule: Ozone
Molecule: Oxygen
Molecule: Helium
Molecule: Sulfuric Acid
Molecule: Carbon Dioxide
-----------------------------------
After clearing the list ...
There is no molecule to show.
===================================
Press any key to continue . . .

Previous Copyright © 2001-2021, FunctionX Next