[c#] Unable to Cast from Parent Class to Child Class

I am trying to cast from a parent class to a child class but I get an InvalidCastException. The child class only has one property of type int. Does anyone know what I need to do?

This question is related to c#

The answer is


Paul, you didn't ask 'Can I do it' - I am assuming you want to know how to do it!

We had to do this on a project - there are many of classes we set up in a generic fashion just once, then initialize properties specific to derived classes. I use VB so my sample is in VB (tough noogies), but I stole the VB sample from this site which also has a better C# version:

http://www.eggheadcafe.com/tutorials/aspnet/a4264125-fcb0-4757-9d78-ff541dfbcb56/net-reflection--copy-cl.aspx

Sample code:

Imports System
Imports System.Collections.Generic
Imports System.Reflection
Imports System.Text
Imports System.Diagnostics

Module ClassUtils

    Public Sub CopyProperties(ByVal dst As Object, ByVal src As Object)
        Dim srcProperties() As PropertyInfo = src.GetType.GetProperties
        Dim dstType = dst.GetType

        If srcProperties Is Nothing Or dstType.GetProperties Is Nothing Then
            Return
        End If

        For Each srcProperty As PropertyInfo In srcProperties
            Dim dstProperty As PropertyInfo = dstType.GetProperty(srcProperty.Name)

            If dstProperty IsNot Nothing Then
                If dstProperty.PropertyType.IsAssignableFrom(srcProperty.PropertyType) = True Then
                    dstProperty.SetValue(dst, srcProperty.GetValue(src, Nothing), Nothing)
                End If
            End If
        Next
    End Sub
End Module


Module Module1
    Class base_class
        Dim _bval As Integer
        Public Property bval() As Integer
            Get
                Return _bval
            End Get
            Set(ByVal value As Integer)
                _bval = value
            End Set
        End Property
    End Class
    Class derived_class
        Inherits base_class
        Public _dval As Integer
        Public Property dval() As Integer
            Get
                Return _dval
            End Get
            Set(ByVal value As Integer)
                _dval = value
            End Set
        End Property
    End Class
    Sub Main()
        ' NARROWING CONVERSION TEST
        Dim b As New base_class
        b.bval = 10
        Dim d As derived_class
        'd = CType(b, derived_class) ' invalidcast exception 
        'd = DirectCast(b, derived_class) ' invalidcast exception
        'd = TryCast(b, derived_class) ' returns 'nothing' for c
        d = New derived_class
        CopyProperties(d, b)
        d.dval = 20
        Console.WriteLine(b.bval)
        Console.WriteLine(d.bval)
        Console.WriteLine(d.dval)
        Console.ReadLine()
    End Sub
End Module

Of course this isn't really casting. It's creating a new derived object and copying the properties from the parent, leaving the child properties blank. That's all I needed to do and it sounds like its all you need to do. Note it only copies properties, not members (public variables) in the class (but you could extend it to do that if you are for shame exposing public members).

Casting in general creates 2 variables pointing to the same object (mini tutorial here, please don't throw corner case exceptions at me). There are significant ramifications to this (exercise to the reader)!

Of course I have to say why the languague doesn't let you go from base to derive instance, but does the other way. imagine a case where you can take an instance of a winforms textbox (derived) and store it in a variable of type Winforms control. Of course the 'control' can move the object around OK and you can deal with all the 'controll-y' things about the textbox (e.g., top, left, .text properties). The textbox specific stuff (e.g., .multiline) can't be seen without casting the 'control' type variable pointing to the textbox in memory, but it's still there in memory.

Now imagine, you have a control, and you want to case a variable of type textbox to it. The Control in memory is missing 'multiline' and other textboxy things. If you try to reference them, the control won't magically grow a multiline property! The property (look at it like a member variable here, that actually stores a value - because there is on in the textbox instance's memory) must exist. Since you are casting, remember, it has to be the same object you're pointing to. Hence it is not a language restriction, it is philosophically impossible to case in such a manner.


To cast, the actual object must be of a Type equal to or derived from the Type you are attempting to cast to...

or, to state it in the opposite way, the Type you are trying to cast it to must be the same as, or a base class of, the actual type of the object.

if your actual object is of type Baseclass, then you can't cast it to a derived class Type...


A variation on the serialization approach for those using ServiceStack:

var child = baseObject.ConvertTo<ChildType>();

or the more verbose:

var child = baseObject.ToJson().FromJson<ChildType>();

ServiceStack's serialization might be super fast and all, but clearly, this is not a solution for massive conversions in low-latency transfers, nor for highly complex types. That's likely obvious to anyone using ServiceStack, but thought I'd clarify in anticipation of comments.


As for me it was enough to copy all property fields from the base class to the parent like this:

using System.Reflection;

public static ChildClass Clone(BaseClass b)
{
    ChildClass p = new ChildClass(...);

    // Getting properties of base class

    PropertyInfo[] properties = typeof(BaseClass).GetProperties();

    // Copy all properties to parent class

    foreach (PropertyInfo pi in properties)
    {
        if (pi.CanWrite)
            pi.SetValue(p, pi.GetValue(b, null), null);
    }

    return p;
}

An universal solution for any object can be found here


As of C# 7.0, you can use the is keyword to do this :

With those class defined :

class Base { /* Define base class */ }
class Derived : Base { /* Define derived class */ }

You can then do somehting like :

void Funtion(Base b)
{
    if (b is Derived d)
    {
        /* Do something with d which is now a variable of type Derived */
    }
}

Which would be equivalent to :

void Funtion(Base b)
{
    Defined d;
    if (b is Derived)
    {
        d = (Defined)b;
        /* Do something with d */
    }
}

You could now call :

Function(new Derived()); // Will execute code defined in if

As well as

Function(new Base()); // Won't execute code defined in if

That way you can be sure that your downcast will be valid and won't throw an exception !


There are some cases when such a cast would make sense.
I my case, I was receiving a BASE class over the network, and I needed more features to it. So deriving it to handle it on my side with all the bells and whistles I wanted, and casting the received BASE class into the DERIVED one was simply not an option (Throws InvalidCastException of Course)

One practical think-out-of-the-box SOLUTION was to declare an EXTENSION Helper class that was NOT inheriting BASE class actually, but INCLUDING IT as a member.

public class BaseExtension
{
   Base baseInstance;

   public FakeDerived(Base b)
   {
      baseInstance = b;
   }

   //Helper methods and extensions to Base class added here
}

If you have loose coupling and just need a couple of extra features to base class without REALLY having an absolute need of derivation, that could be a quick and simple workaround.


You can't cast a mammal into a dog - it might be a cat.

You can't cast a food into a sandwich - it might be a cheeseburger.

You can't cast a car into a Ferrari - it might be a Honda, or more specifically, You can't cast a Ferrari 360 Modena to a Ferrari 360 Challange Stradale - there are differnt parts, even though they are both Ferrari 360s.


That would violate object oriented principles. I'd say an elegant solution here and elsewhere in the project is using a object mapping framework like AutoMapper to configure a projection.

Here's a slighty more complex configuration than is neccessary but is flexible enough for most cases:

public class BaseToChildMappingProfile : Profile
{
    public override string ProfileName
    {
        get { return "BaseToChildMappingProfile"; }
    }

    protected override void Configure()
    {
        Mapper.CreateMap<BaseClass, ChildClassOne>();
        Mapper.CreateMap<BaseClass, ChildClassTwo>();
    }
}


public class AutoMapperConfiguration
{
    public static void Configure()
    {
        Mapper.Initialize(x =>
        {
            x.AddProfile<BaseToChildMappingProfile>();
        });
    }
}

When application starts call AutoMapperConfiguration.Configure() and then you can project like this:

ChildClassOne child = Mapper.Map<BaseClass, ChildClassOne>(baseClass);

Properties are mapped by convention so if the class is inherited the property names are exactly the same and mapping is configured automatically. You can add additional properties by tweaking the configuration. See the documentation .


The instance of the object should be created using the child class's type, you can't cast a parent type instance to a child type


I have seen most of the people saying explicit parent to child casting is not possible, that actually is not true. Let's take a revised start and try proving it by examples.

As we know in .net all castings have two broad categories.

  1. For Value type
  2. For Reference type (in your case its reference type)

Reference type has further three main situational cases in which any scenario can lie.

Child to Parent (Implicit casting - Always successful)

Case 1. Child to any direct or indirect parent

Employee e = new Employee();
Person p = (Person)e; //Allowed

Parent to Child (Explicit casting - Can be successful)

Case 2. Parent variable holding parent object (Not allowed)

Person p = new Person();  // p is true Person object
Employee e = (Employee)p; //Runtime err : InvalidCastException <-------- Yours issue

Case 3. Parent variable holding child object (Always Successful)

Note: Because objects has polymorphic nature, it is possible for a variable of a parent class type to hold a child type.

Person p = new Employee(); // p actually is Employee
Employee e = (Employee)p; // Casting allowed

Conclusion : After reading above all, hope it will make sense now like how parent to child conversion is possible(Case 3).

Answer To The Question :

Your answer is in case 2.Where you can see such casting is not allowed by OOP and you are trying to violate one of OOP's basic rule.So always choose safe path.

Further more, to avoid such exceptional situations .net has recommended using is/as operators those will help you to take informed decisions and provide safe casting.


The instance that your base class reference is referring to is not an instance of your child class. There's nothing wrong.

More specifically:

Base derivedInstance = new Derived();
Base baseInstance = new Base();

Derived good = (Derived)derivedInstance; // OK
Derived fail = (Derived)baseInstance; // Throws InvalidCastException

For the cast to be successful, the instance that you're downcasting must be an instance of the class that you're downcasting to (or at least, the class you're downcasting to must be within the instance's class hierarchy), otherwise the cast will fail.