Reputation: 127
Base to Derived is possible(Boxing). But Derived to base gives run time exception, however that is equivalent to Unboxing. Why is it so
Base b = new Base();
Child c = new Child();
c = (child)b; // No compilation error but run time error
object a;
int i = (int)a; //No error Unboxing
Is it possible because object is top class all value type or Ref type inherited by Object class. public int ConvertToINT(object obj) { int i = (int)obj; return Convert.ToInt32(obj); }
Upvotes: 3
Views: 1989
Reputation: 26398
I might get downvoted for this; but there is a way to flirt with dealing with higher derived objects; if that is what you want to accomplish. This isn't up-casting; this is Contravarience; which allows you to call higher derived interface object so long as you don't require the T value to be returned at any time.
internal interface IVet<in T> where T : Animal
{
void Set(T animal);
void Heal();
}
class Animal
{
public virtual void Examine(){Console.WriteLine("Animal");}
}
class Cat : Animal
{
public override void Examine(){Console.WriteLine("Cat");}
}
internal class Vet<T> : IVet<T> where T : Animal
{
private T _value;
public void Set(T animal)
{
_value = animal;
}
public void Heal()
{
_value.Examine();
}
}
So you can do things like this
internal class Program
{
private static void Main(string[] args)
{
IVet<Animal> _vetAnimal = new Vet<Animal>();
IVet<Cat> _vetCat = _vetAnimal;
_vetCat.Set(new Cat());
_vetCat.Heal();
}
}
Notice we have a Vet<Animal>
object and we assign it to the contravarient interface IVet<Cat>
. We can then use this interface to pass a 'Cat' variable and do something with it. So contravariance lets to you make the cast from IVet<Animal>
to IVet<Cat>
.
Useful is some circumstances; but again, not upcasting of a value... basically a wrapper where you can elevate the interface's generic type.
Upvotes: 1
Reputation: 109537
You are confusing value boxing with reference casting.
If you do this:
int x = 1;
object a = x;
int i = (int) a;
Then the line object a = x;
is boxing the integer value of x by (effectively) creating a wrapper class that contains the integer value 1
.
When you unbox it by casting it back to int
the runtime code checks that its underlying type is correct (an int
, because you are casting to int
), and then it extracts the underlying value and assigns it to the target int variable.
If you do this:
public class BaseClass
{
}
public class DerivedClass: BaseClass
{
public int Value;
}
...
BaseClass b = new BaseClass();
DerivedClass d = (DerivedClass) b;
int myValue = d.Value; // What would happen? BaseClass doesn't have a Value property!
No boxing is involved here because we are working with reference types. Instead, this code is trying to treat a base class as if it was a derived class.
This is clearly impossible, because for example what would happen if you then tried to access DerivedClass.Value
? This property doesn't exist in the base class, so it's impossible to treat an instance of the base class as a derived class.
Upvotes: 3
Reputation: 56697
You're misunderstanding some OOP concepts. While it is true that you can use a derived class when the base class is required, you can not go the other way.
These work:
Base b1 = new Base();
Base b2 = new Child();
Base b3 = (Base)b2;
This does not work, as a Base
simply is not a Child
:
Base b1 = new Base();
Child c1 = (Child)b1;
To speak in the well know Vehicle
examples:
While a truck is still a vehicle (every Child
is also a Base
), not every vehicle is a truck (not every Base
is also a Child
).
Upvotes: 0
Reputation: 13382
from msdn Boxing and Unboxing
Boxing is the process of converting a value type to the type object or to any interface type implemented by this value type.
in your sample
Base b = new Base();
Child c = new Child();
c = (Child)b; // No compilation error but run time error
you create two different object and try cast it, this is not the same as
Base b = new Child();
Child c = new Child();
c = (Child)b; // No compilation error, no run time error if Child derived from Base
Upvotes: 1