Question

I know that in a widening conversion, the destination data type can hold any value provided by the source data type. I can understand this when convert value type, but can't between reference types. My question arises from follows scenario:

public class Person
{
    public string Name { get; set; }
}

public class Employee : Person
{
    public string SurName { get; set; }
}
static void Main(string[] args)
{
    Employee emp = new Employee { Name = "Elvin", SurName = "Mammadov" };
    Person prs = emp;
}

As shown, the Person class is ancestor class of Empoyee. In previouse code, I create reference of Emplyee class, and then convert Employee object into a Person. At this point, I lose SurName data field and value.

I want to know:

  1. Is it countary to can hold any value expression?

  2. Why conversion a reference type to a direct or indirect ancestor class or interface is a widening conversion?

thanks for reply

Was it helpful?

Solution

It would be called a 'widening conversion' because you're becoming less specific with regard to the references type, you're widening the set of potential types. When you have an Employee reference you know that you can use any functionality specific to that class, when you have a Person reference to the same object you only know that you can use functionality contained in the Person class. If you want to use Employee specific functionality with your prs reference you'll first have to cast your reference back to an Employee reference and if prs isn't actually of type Employee (perhaps it's of type Customer which also inherits from Person) then you will get an InvalidCastException.

The SurName property does not go away when you're dealing with a Person reference. You just cannot access it because it is not contained within the Person class. Basically, if you have a reference of the base classes type, you will only be able to access properties/methods contained within the base class. It doesn't matter that it is actually an Employee, you have a Person reference, so the object is treated accordingly.

The conversion is not useful in your example. The conversion is useful when you're attempting to work with many child classes in a generic manner. As an example, I may have a Person class. In addition to that I have Employee, Customer, and Consultant classes which inherit from it. Now lets suppose I have a Store object and I want to do something like get the names of every Person who is currently in the store. The simplest way to solve this problem would be to have a List<Person> with all the people in the store. Because Employee, Customer, and Consultant all inherit from Person I could do

peopleInMyStore.Add(MyEmployee);
peopleInMyStore.Add(MyCustomer);
peopleInMyStore.Add(MyConsultant);

Then later on I can do something like;

foreach (Person p in peopleInMyStore)
{
     Console.WriteLine(p.Name);
}

This concept is referred to as 'polymorphism' and can be read about here http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

My example is contrived, but this is one of the main reasons you use inheritance. To give you a real example I have some test code where I have a class called ApiTestSuite then I have about a dozen classes that all inherit from it of the form SpecificApiTestSuite. The project builds into a command line executable, you invoke it with an api parameter (api=specificApiName) then I can do something like;

 ApiTestSuite tests;
 if (args[0] == "api1")
     tests = new Api1TestSuite();
 else
     tests = new Api2TestSuite();
 tests.RunTests();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top