Cast arrays from one reference type to another in C#

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 Employees into an array of Persons.

// 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.

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.

This 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 (Person employee in employees)
    {
        lstModifiedEmployees.Items.Add(employee.GetName());
    }
}

The code first creates an array of Employees. It then loops through the Employees 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's name.

Finally the program loops through the arrays again to show the results in the Person array and the Employee array. 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 Employees so they would use the Employee class's version of the method even if you refer to an object by a Person reference. For more information on virtual methods, see Override a virtual parent class method in a child class in C#.)

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.