• 0

Upcasting and Downcasting an Array


Question

Here there are 2 classes Employee(base class) and Manager(sub class) Manager inherits from Employee.I have added 2 Interfaces IName and ISalary so that i can downcast.

 

interface IName
{
    string Name { get; }
    void MyName();
}

 interface ISalary
{
    string Salary { get; }
    void MySalary();
}

class Employee : IName
{
  public Employee (string name)
    {
        this.name = name;
    }

    private string name;


    public string Name
    {
        get { return " My name is " + name; }
    }

    public void MyName()
    {
        MessageBox.Show(this.Name);
    }
}

class Manager : Employee, ISalary
{
    public Manager(string name, int salary) : base(name)
    {
        this.salary = salary;
    }

    private int salary;
    private int name;

    public string Salary
    {
        get { return name + " Salary : " + salary + " per month"; }
    }
    public void MySalary()
    {
        MessageBox.Show(this.Salary);
    }

}

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Manager[] manager = new Manager[2];
        manager[0] = new Manager("Joe", 400);
        manager[1] = new Manager("John", 500);

        Employee[] employee = manager;
        ISalary someemployee = employee as Manager;
        someemployee.MySalary();

    }
}

Here are the errors that i'm getting

 

Cannot convert type 'WindowsFormsApplication26.Employee[]' to 'WindowsFormsApplication26.Manager' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

 

When downcasting the conversion returns to null.

 

Also Under manager class i have to mention the line  

private string name ;

despite using the base keyword in the constructor above it. Otherwise the name parameter is not recognized by the class.

Link to comment
https://www.neowin.net/forum/topic/1322268-upcasting-and-downcasting-an-array/
Share on other sites

3 answers to this question

Recommended Posts

  • 0
Employee[] employee = manager;
ISalary someemployee = employee as Manager;

employee is an array. someemployee is not an array. You're trying to assign a collection of values to a single value, which makes no sense. Maybe you meant:

 

Employee[] employee = manager;
ISalary someemployee = employee[0]; // get the first employee in the array

And that doesn't make sense either, because Employee doesn't implement ISalary. The compiler won't let you do that, and trying to work around the compiler error with a cast will just turn the compile-time problem into a run-time problem. You could do:

 

Employee[] employee = manager;
ISalary someemployee = employee[0] as Manager; // get the first employee in the array

And incidentally, in this case, it won't fail at run-time, because you've actually only put Manager objects in that Employee array, and Manager implements ISalary. But this is terrible. If you ever put an actual Employee in that Employee array, the code will fail.

 

In general, casting arrays is bad, don't do it. It's in C# because C# copied Java without thinking on that point.

 

It's unclear what you're trying to do and why you need casts at all (or even arrays or even any class besides the form here). But at least this is explanation of what's wrong with your code.

 

  Quote

Also Under manager class i have to mention the line  

private string name ;

despite using the base keyword in the constructor above it. Otherwise the name parameter is not recognized by the class.

Expand  

Because it's private in the base class. "private" means that it's only visible to that class and nothing else, including derived classes. If you want it to be visible in derived classes you need it to be "protected".

 

Realize that adding private string name ; in the Manager class means the Manager class now has two fields called name: one only visible in the base class and one only visible in the derived class, each with its own value. This is very confusing and definitely not what you want.

  • 0
  On 13/02/2017 at 20:41, Andre S. said:
Employee[] employee = manager;
ISalary someemployee = employee as Manager;

employee is an array. someemployee is not an array. You're trying to assign a collection of values to a single value, which makes no sense. Maybe you meant:

 

Employee[] employee = manager;
ISalary someemployee = employee[0]; // get the first employee in the array

And that doesn't make sense either, because Employee doesn't implement ISalary. The compiler won't let you do that, and trying to work around the compiler error with a cast will just turn the compile-time problem into a run-time problem. You could do:

 

Employee[] employee = manager;
ISalary someemployee = employee[0] as Manager; // get the first employee in the array

And incidentally, in this case, it won't fail at run-time, because you've actually only put Manager objects in that Employee array, and Manager implements ISalary. But this is terrible. If you ever put an actual Employee in that Employee array, the code will fail.

 

In general, casting arrays is bad, don't do it. It's in C# because C# copied Java without thinking on that point.

 

It's unclear what you're trying to do and why you need casts at all (or even arrays or even any class besides the form here). But at least this is explanation of what's wrong with your code.

 

Because it's private in the base class. "private" means that it's only visible to that class and nothing else, including derived classes. If you want it to be visible in derived classes you need it to be "protected".

 

Realize that adding private string name ; in the Manager class means the Manager class now has two fields called name: one only visible in the base class and one only visible in the derived class, each with its own value. This is very confusing and definitely not what you want.

Expand  

Ok i changed the code as you mentioned and i was able to get the output, So if i want the variables of employee[1] to be displayed do i need to create another instance of  ISalary like

 

ISalary someotheremployees = employee[1] as Manager;

someotheremployee.MySalary(); 

 

or is there another way of representing employee[0] and employee[1]  in a single line so that the output message box displays  both of their values one after the other

 

  • 0
  On 14/02/2017 at 13:14, Ch33f said:

Ok i changed the code as you mentioned and i was able to get the output, So if i want the variables of employee[1] to be displayed do i need to create another instance of  ISalary like

 

ISalary someotheremployees = employee[1] as Manager;

someotheremployee.MySalary(); 

 

or is there another way of representing employee[0] and employee[1]  in a single line so that the output message box displays  both of their values one after the other

Expand  

The basic problem is that you have 2 Managers you want to display, but for some reason, you insist on storing them inside an Employee array, only to be forced to cast them back to Managers (a perilous operation, as I mentioned) before displaying them.

 

This begs the question: why store them in an Employee array at all? Why not just use your original Manager array? It's unclear why you're doing things this way.

 

By the way you are not "creating another instance of ISalary" with the code you showed. You are creating another variable pointing to the same instance.

 

If you want to display the values of the array one after the other, just use a loop to go through the array (ex.: foreach).

This topic is now closed to further replies.