• 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.
  • Posts

    • Scientists uncover bizarre new material that's breaking one of the laws of this Universe by Sayan Sen Image by Ron Lach via Pexels Scientists from the University of Chicago and UC San Diego have discovered a group of materials that behave in surprising ways when put under heat, pressure or electricity. Instead of responding like most materials, these can shrink when heated, expand when compressed, and even bounce back to their original state with the right electric charge. The work focuses on oxygen-redox (OR) materials—types that can help batteries store more energy but typically suffer from stability problems due to structural disorder. In their normal state, the materials follow the usual rules of thermodynamics. But in what's called a “metastable” state, a kind of temporary balance, they behave in reverse. “When heated, the material shrinks instead of expanding,” said Prof. Shirley Meng, senior author of the study published in Nature. This is linked to what’s known as a disorder–order transition inside the material’s structure. The team recorded a negative thermal expansion rate of −14.4(2) × 10⁻⁶ °C⁻¹, which means the material actually contracts when warmed up. This goes against a common theory called the Grüneisen relationship, which usually explains why materials expand with heat. And pressure? Even stranger. When they pushed the material on all sides at levels seen in Earth's tectonic plates, it expanded instead of getting smaller. “Negative compressibility is just like negative thermal expansion,” explained Prof. Minghao Zhang. “If you compress a particle of the material in every direction… it will expand.” They also found that electricity can reset the material’s structure. By tweaking the voltage limits, they recovered almost 100% of the original structure and performance. This has big potential for battery tech, especially electric vehicles (EVs). “When we use the voltage, we drive the material back to its pristine state. We recover the battery,” said Zhang. He added: “You just do this voltage activation… your car will be a new car. Your battery will be a new battery.” The research may lead to materials with zero thermal expansion, helpful in everything from buildings to aircraft. Zhang noted, “Take every single building, for example. You don't want the materials making up different components to change volume that often.” As they move forward, the team wants to understand how redox chemistry can further control these effects and expand practical uses. “One of the goals is bringing these materials from research to industry,” said co-first author Bao Qiu. Their work opens up a new way of thinking about material design, where energy doesn’t just power devices, but reshapes the building blocks themselves. Source: University of Chicago, Nature This article was generated with some help from AI and reviewed by an editor. Under Section 107 of the Copyright Act 1976, this material is used for the purpose of news reporting. Fair use is a use permitted by copyright statute that might otherwise be infringing.
    • "Elon Musk says a kid-friendly 'Baby Grok' is on the way" No kid wants to be a baby anymore. "Kid friendly" I would have named it "Kid Grok"
    • TP-Link Tri-Band AXE5400 Wi-Fi 6E Gaming Router Archer GXE75 is just $135 by Sayan Sen If you’re juggling gaming consoles, 4K streams and a growing roster of smart devices, the TP-Link Archer GXE75 Tri-Band AXE5400 Wi-Fi 6E Gaming Router is a good option to look at right now, considering the device is currently on sale at just $135 (purchase link under the specs table below). The Archer GXE75 promises up to 5.4 Gbps of throughput across three bands: 574 Mbps on 2.4 GHz, 2402 Mbps on 5 GHz and 2402 Mbps on 6 GHz (HE160 channels enabled). A 2.5 Gbps WAN/LAN port pairs with three 1 Gbps LAN ports and a USB 3.0 port for fast file sharing or printer access (purchase link down below). The quad-core CPU and 512 MB of RAM should help to handle multiple streams without bogging down, while MU-MIMO, OFDMA and 1024-QAM improve efficiency when several devices connect simultaneously. The router’s built-in Game Accelerator engine is said to automatically prioritize gaming packets (both wired and wireless), and TP-Link’s GPN (Gamers Private Network) acceleration can reduce packet loss for supported titles. HomeShield security brings firewall protection, device quarantining and parental controls. The technical specifications of the router are given below: Specification Details Wireless Standards IEEE 802.11ax 6 GHz; IEEE 802.11ax/ac/n/a 5 GHz; IEEE 802.11ax/n/g/b 2.4 GHz Wi-Fi Speeds 6 GHz: 2402 Mbps (802.11ax); 5 GHz: 2402 Mbps (802.11ax); 2.4 GHz: 574 Mbps (802.11ax) Spatial Streams 6 streams (tri-band OFDMA/MU-MIMO) Processor 1.7 GHz 64-bit Quad-Core CPU Memory 512 MB high-speed RAM Ethernet Ports 1× 2.5 Gbps WAN/LAN; 1× 1 Gbps WAN/LAN; 3× 1 Gbps LAN USB 1× USB 3.0 SuperSpeed port (up to 10× faster than USB 2.0) Antennas 4× high-performance external antennas with Beamforming Buttons Power On/Off; Reset; WPS/Wi-Fi; LED On/Off Working Modes Router Mode; Access Point Mode Security WPA, WPA2, WPA3, WPA/WPA2-Enterprise; SPI firewall; Access Control; IP/MAC binding; Application-layer gateway; HomeShield security suite VPN OpenVPN, PPTP, L2TP (server & client); WireGuard (server & client) Software & Services IPv4/IPv6; TP-Link HomeShield; EasyMesh; Parental controls; QoS by device; WAN types (Dynamic IP, Static IP, PPPoE, PPTP, L2TP); DDNS (TP-Link, NO-IP, DynDNS); auto firmware updates Gaming Features Game QoS boost; gaming-port priority; Gamers Private Network acceleration; game-port forwarding; real-time game panel with stats & RGB control Operating Environment 0 °C – 40 °C; 10 %– 90 % non-condensing humidity Get the TP-Link Tri-Band AXE5400 Wi-Fi 6E Gaming Router Archer GXE75 at the link below: TP-Link Tri-Band AXE5400 Wi-Fi 6E Gaming Router Archer GXE75 | EasyMesh, HomeShield: $159.99 + $25 off with coupon => $134.99 (Sold and Shipped by Amazon US This Amazon deal is US-specific and not available in other regions unless specified. If you don't like it or want to look at more options, check out the Amazon US deals page here. Get Prime (SNAP), Prime Video, Audible Plus or Kindle / Music Unlimited. Free for 30 days. As an Amazon Associate, we earn from qualifying purchases.
    • Oh no... here we go again. Tha same sh*t that happaned to Mail & Calendar...
  • Recent Achievements

    • Rookie
      Snake Doc went up a rank
      Rookie
    • First Post
      nobody9 earned a badge
      First Post
    • One Month Later
      Ricky Chan earned a badge
      One Month Later
    • First Post
      leoniDAM earned a badge
      First Post
    • Reacting Well
      Ian_ earned a badge
      Reacting Well
  • Popular Contributors

    1. 1
      +primortal
      495
    2. 2
      Michael Scrip
      203
    3. 3
      ATLien_0
      197
    4. 4
      Xenon
      137
    5. 5
      +FloatingFatMan
      116
  • Tell a friend

    Love Neowin? Tell a friend!