Hi Guys
NP142 why is casting not needed
http://www.aspfree.com/c/a/C-Sharp/Behind-the-Scenes-Look-at-C-Sharp-Type-Conversions/
Following program is in the above website. Article is saying that Person aPerson = worker1; doesn't need casting, because here there's no lose of data. But there is a type change worker1 is Worker type, it is becoming Person type therefore in my view if there is a type change casting is needed.
But whether worker1 is cased or not output of the program is not altered.
Please explain the reason.
Thank you
using System;
namespace TypeConversion
{
class Class1
{
static void Main(string[] args)
{
Worker worker1 = new Worker();
worker1.FirstName = "Michael";
worker1.LastName = "Youssef";
worker1.Department = "IT";
Console.WriteLine(worker1);
Console.WriteLine();
Person aPerson = worker1; // this doesn't require a cast
Console.WriteLine("this is aPerson = {0}", aPerson);
Worker worker2 = (Worker)aPerson; // this requires a cast operation
Console.WriteLine("this is worker2 = {0}", worker2);
Console.ReadLine();
}
}
class Person
{
private string firstName;
private string lastName;
public string FirstName
{
get{return this.firstName;}
set{this.firstName = value;}
}
public string LastName
{
get{return this.lastName;}
set{this.lastName = value;}
}
public override string ToString()
{
return this.firstName + " " + this.lastName;
}
}
class Worker : Person
{
private string department;
public string Department
{
get{return this.department;}
set{this.department = value;}
}
public override string ToString()
{
return this.FirstName + " " + this.LastName + "," + this.department;
}
}
}
/*
Michael Youssef,IT
this is aPerson = Michael Youssef,IT
this is worker2 = Michael Youssef,IT
*/
AlanPosted Aug 30, 2008, 7:52 AM
The point is that the Worker class derives from the Person class and so a Worker is a Person.
That being so, you can always assign a Worker object to a variable of type Person. A cast is not needed because a derived object is implicitly convertible to its parent type.
Posted Sep 1, 2008, 6:32 AM
This is excellent explanation. I only had prior knowledge of Turbo Pascal not C++. Thank you very much for elaboration.
AlanPosted Aug 31, 2008, 6:43 PM
Well, you need to distinguish between the objects themselves and the variables which refer to them.
aPerson is a variable (or object reference) of type Person. It contains a reference (i.e. a pointer) to where a Person object is stored in memory or, if it doesn't currently refer to an object, it contains a null pointer (all bytes zero).
So, in this line:
Person aPerson = new Person();
the expression on the RHS causes a new object of type Person to be created and stored on the heap. A pointer to where this object is stored is then assigned to the variable (or object reference) aPerson.
In this line:
Person aPerson = worker1;
the variable worker1 already contains a reference to an object of type Worker and, when this is assigned to the variable aPerson, aPerson also now contains a reference to that object.
The difference is that worker1 can be used to call any accessible member of the object but aPerson can only call accessible members which a Worker object shares with its Parent class, Person.
If you now consider this line:
aPerson = null;
then aPerson no longer points to any object i.e. it contains a null pointer which is four zero bytes on a 32 bit system.
In C++ pointers are explicit but in C# they are not. This makes the language much simpler but you sometimes need to think out what's happening behind the scenes until constant practice makes it second nature to you.
Posted Aug 31, 2008, 4:33 PM
I guessed the meaning of the above sentence. But it is confusing.
Person aPerson = worker1; // this is object reference aPerson
Person aPerson = new Person(); //this is object of type Person
Why in this code (Person aPerson = worker1;) aPerson can’t be called object of type Person?AlanPosted Aug 31, 2008, 10:16 AM
Yes, it could mean that or, more generally, that there's an expression on the RHS of the assignment statement which evaluates to a Person object. For example:
Person bPerson = new Person();
Person aPerson = bPerson; // here bPerson is an expression of type Person
Posted Aug 31, 2008, 8:29 AM
“If the object reference aPerson refers to an object of type Person......” (highlighted above in blue) means if code
Person aPerson = new Person(); exist in the program.
AlanPosted Aug 31, 2008, 5:51 AM
If you assign a Worker object to a Person variable, then you know that you can call any accessible member of Person using that variable because Worker (being a derived class of Person) must inherit all the members which Person has.
However, this doesn't work the other way around. If the Person variable actually contains a reference to a Person rather than a Worker, then this statement will fail at runtime despite the cast:
Worker worker2 = (Worker)aPerson;
The reason is that Worker contains members which Person doesn't and so if you tried to call one of those 'extra' members using the worker2 variable, there would be nothing there to call! The runtime makes sure this situation can't arise by throwing an InvalidCastException when it discovers that aPerson actually contains a reference to a Person object.
If aPerson had contained a reference to a Worker object instead, then there would have been no problem and no exception would have been thrown.
In other words a Worker is a Person but a Person is not a Worker!
Posted Aug 30, 2008, 3:43 PM
http://www.aspfree.com/c/a/C-Sharp/Behind-the-Scenes-Look-at-C-Sharp-Type-Conversions-continued/1/
In the above website 8th paragraph says that:
If the object reference aPerson refers to an object of type Person, then the statement Worker worker2 = (Worker)aPerson; will fail. It will generate the exception System.InvalidCastException because a Worker object contains more members than a Person object. We can't cast that way, as we get a exception of type System.OverflowException when we assign a value that exceeds the maximum range for the value type (when runs it a checked block).
That mean Worker object range is bigger than the Person object range. So why does it generate exception System.InvalidCastException?