AmitykSharma
AmitykSharma

Reputation: 127

Base to Derived is possible(Boxing), But Derived to base gives run time exception, however that is equivalent to Unboxing

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

Answers (4)

Meirion Hughes
Meirion Hughes

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

Matthew Watson
Matthew Watson

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

Thorsten Dittmar
Thorsten Dittmar

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

Grundy
Grundy

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

Related Questions