Reputation: 27387
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:
Is it countary to can hold any value expression?
Why conversion a reference type to a direct or indirect ancestor class or interface is a widening conversion?
thanks for reply
Upvotes: 2
Views: 1518
Reputation: 48086
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();
Upvotes: 4