0

I have following code that I learn on. I know I cannot implicitly convert "parent" to "child" (but I can do it vice versa). However, I am trying to explicitly convert but cannot get it working. I assume the child should lose data when converted to parent.

class Parent
{
    int A=5;
}

class Child:Parent
{
    int B=5;
    int C=2;
}

Parent parent = new Parent();
Child ch = new Child();

ch=ch as Parent //or (Parent)ch;
Igor Korkhov
  • 8,283
  • 1
  • 26
  • 31
John V
  • 4,855
  • 15
  • 39
  • 63
  • `I assume the child should lose data when converted to parent.` No. You seem to have some very bad ideas on how some vital concepts in c# work. I reccomend Jon Skeet's book, C# in Depth, and reading msdn documentation, and possible poking around the written specification. http://msdn.microsoft.com/en-us/library/ms173149(v=vs.80).aspx – asawyer Mar 06 '12 at 12:50
  • @asawyer thanks but what about conversion from double to int - there is a loss of data – John V Mar 06 '12 at 12:53
  • 1
    This is exactly what I mean. `double` to `int` has no inheritance chain. Your dealing with apples and oranges here, and mixing the terminology. – asawyer Mar 06 '12 at 12:54

7 Answers7

4

why do you need to do this? A Child is a Parent due to the inheritence relationship. Anywhere you need a Parent you can pass a Child and it should work (and if it doesn't you are violating the Liskov Substitution Principle).

You can look at the Child as if it was a Parent like so:

 Child ch = new Child();
 Parent childAsParent = ch as Parent;

but is fairly pointless...

The difference between using the as Parent and the (Parent) is whether you'll get an error or not. The 'safe' cast (using as) will just leave you with null if ch is not an instance of Parent, which in this case it always will be. The other will throw an InvalidCastException if the cast can't be done.

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
3

ch is a Parent, there is no need to do that cast

if you test this expression

bool isParent = ch is Parent

you'll see that isParent = true. You can use ch as Parent anywhere without using any cast

Claudio Redi
  • 67,454
  • 15
  • 130
  • 155
2

You need to set your type to the correct type when casting...

Child ch = child as Parent; //Wrong
Child ch = (Parent)child;   //Wrong
Parent p = child as Parent; //Correct
Parent p = (Parent)child;   //Correct
var p = child as Parent;    //Correct (var will end up being a Parent)
var p = (Parent)child;      //Correct (var will end up being a Parent)

The different types of cast can be explained here (StackOverflow Question).


I assume the child should lose data when converted to parent.

This is an incorrect assumption. You aren't "losing" data, but you're changing the type, which changes what members you can access. Change it back to a Child and the members B and C still retain their values.

Community
  • 1
  • 1
myermian
  • 31,823
  • 24
  • 123
  • 215
0

The problem is that ch is a Child, and you are trying to assign a Parent to it. Have you tried replacing the last line with

Parent pa = ch as Parent;
Øyvind Bråthen
  • 59,338
  • 27
  • 124
  • 151
0

Change

Parent parent = new Parentk(); 
Child ch = new Child(); 
ch=ch as Parent //or (Parent)ch; 

by

Parent parent = new Parent(); 
Child ch = new Child(); 
parent=ch as Parent //or (Parent)ch; 

You cast a child to a parent but the result is a child object

Julien
  • 3,509
  • 20
  • 35
0

modify your last lines to

Parent castRef = ch as Parent; 
Parent castRef = (Parent)ch;

The former is a "safe cast" it will check if ch is actually a Parent type (or a decendant of) and return a reference to the Parent class if it is and null if not. This goes hand in hand with the as operator (as in if (ch is Parent) ... )

The latter is an explicit cast and does not check, ptentially leaving you with a refernce to somthing that is not of (or decended from Parent) that will go oddly wrong when you use it.

I would always prefer the former version.

and to explicty answer your query; you need a new Parent type variable ref to assign the cast into.

Pete Stensønes
  • 5,595
  • 2
  • 39
  • 62
0

Note the difference between an object instance and a reference.

new Child();

instantiates (creates an instance of) the class Child. That means there is now an object (in the "heap") but you do not have direct access to that object, you have indirect access through references to it. Once the object is instantiated, you cannot change it's type.

Child ch;

defines a reference that has a Child interface, that by default refers to no object (IE: null)

Parent parent;

defines a reference that has a Parent interface.

Once these references exist, you can then assign them to objects using lines like:

parent = new Parent();

or

ch = new Child();

Because Child inherits from Parent (as others have said, it "is a" Parent), Parent references can also refer to Child objects. IE:

parent = new Child();

or

parent = ch;

but you will only be able to access the portions of the Child object that are defined by Parent through the Parent reference. Note that a cast is not necessary for this. However, you would need a cast going the other direction. That is, if it is still a Child object, but you only have a Parent reference so far, you need a cast to get a Child reference:

ch = (Child)parent;

or

ch = parent as Child;

The former will throw an exception if the cast cannot be performed. The latter will assign null to ch if the cast cannot be performed.

Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80