Cast arrays from one reference type to another in C#

[cast arrays]

Every C# programmer knows that you can use a cast operator to convert one data type into another. For example, if the Employee class inherits from the Person class, then the following code creates an Employee object and then makes a Person variable that refers to the same object.

Employee employee = new Employee();
Person person = (Person)employee;

An Employee is a kind of Person, so it makes sense that the program should be able to treat an Employee object as if it were a Person object.

Fewer programmers know that you can also cast arrays. For example, the following code casts an array of Employee objects into an array of Person objects.

// Initialize the Employee array.
Employee[] employees =
{
    new Employee(...),
    ...
};

// Cast into an array of Person.
Person[] persons = (Person[])employees;

This creates an array of Person objects. Note that the objects refer to the original objects; they are not new Person objects. It’s as if you had cast each of the objects in the original employees array into Person objects individually.

This example uses the following Person and Employee classes.

class Person
{
    public string FirstName, LastName;
    public Person(string first_name, string last_name)
    {
        FirstName = first_name;
        LastName = last_name;
    }
    public string GetName()
    {
        return FirstName + " " + LastName;
    }
}

class Employee : Person
{
    public int EmployeeId;
    public Employee(string first_name, string last_name, int id)
        : base(first_name, last_name)
    {
        EmployeeId = id;
    }
    public string GetName()
    {
        return base.GetName() + " [" + EmployeeId.ToString() + "]";
    }
}

These classes are relatively straightforward.

The example then uses the following code to demonstrate array casting.

private void Form1_Load(object sender, EventArgs e)
{
    // Make an array of Employees.
    Employee[] employees =
    {
        new Employee("Terry", "Pratchett", 1001),
        new Employee("Christopher", "Moore", 1003),
        new Employee("Jasper", "Fforde", 1002),
        new Employee("Tom", "Holt", 1004),
    };
    foreach (Employee employee in employees)
        lstInitial.Items.Add(employee.GetName());

    // Cast the array into an array of Person.
    Person[] persons = (Person[])employees;
    foreach (Person person in persons)
        lstPersons.Items.Add(person.GetName());

    // Modify the Person objects.
    foreach (Person person in persons)
        person.FirstName = "* " + person.FirstName;

    // Display the modified Person[] array.
    foreach (Person person in persons)
        lstModifiedPersons.Items.Add(person.GetName());

    // Display the modified Employee[] array.
    foreach (Employee employee in employees)
        lstModifiedEmployees.Items.Add(employee.GetName());
}

The code first creates an array of Employee objects. It then loops through those objects calling GetName to add their names to a ListBox.

Next, the code casts the Employee array into an array of Person. It loops through that array calling GetName to add the Person names to a ListBox. (Quick Quiz: Why does the example invent a GetName method instead of overriding the classes’ ToString methods? Answer at the end of this post.)

The program then loops through the Person array and adds an asterisk to each Person object’s first name.

Finally, the program loops through the arrays again to show the results in the Person and Employee arrays. Even though the code changed the objects’ names in the Person array, the changes are seen in the Employee array because both arrays contain references to the same objects.

(Quick Quiz Answer: The Object class’s ToString method is declared virtual. That means if a descendant class overrides it, then that object uses the new version even if it is referenced by an ancestor class. In this example, all of the objects are Employee objects so they would use the Employee class’s version of the method even if you refer to an object by using a Person reference. For more information on virtual methods, see Override a parent class method in C#.)


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in arrays, syntax, variables and tagged , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *