Is it possible to assign a base class object to a derived class reference with an explicit typecast?

Is it possible to assign a base class object to a derived class reference with an explicit typecast in C#?. I have tried it and it creates a run-time error.

user12031933 asked Apr 8, 2009 at 11:12 6,747 18 18 gold badges 72 72 silver badges 100 100 bronze badges

33 Answers 33

No. A reference to a derived class must actually refer to an instance of the derived class (or null). Otherwise how would you expect it to behave?

object o = new object(); string s = (string) o; int i = s.Length; // What can this sensibly do? 

If you want to be able to convert an instance of the base type to the derived type, I suggest you write a method to create an appropriate derived type instance. Or look at your inheritance tree again and try to redesign so that you don't need to do this in the first place.

answered Apr 8, 2009 at 11:15 1.5m 881 881 gold badges 9.3k 9.3k silver badges 9.3k 9.3k bronze badges @Mike: The code compiles just fine. It falls over at execution time though :) Commented Apr 8, 2009 at 12:39

Then what exactly happens when we write Base b= new Derived(); ? Will it create objects for both base and derived class?

Commented Jun 26, 2014 at 8:34

@Akie: No, it creates a single object of type Derived , but you can treat a Derived reference as a Base reference.

Commented Jun 26, 2014 at 8:38

So Is there any difference in resulting object for these two statements? Base b = new Base() and Base b = new Derived()? what is the benefit of using one over other?

Commented Jun 26, 2014 at 8:52

@Akie: Yes, one creates an instance of Base , and the other creates an instance of Derived . If you call a virtual method on b which was overridden in Derived , you'll see the Derived behaviour if you've got an instance of Derived . But it's not really appropriate to go into the details in a Stack Overflow comment thread - you should really read a good C# book or tutorial, as this is pretty fundamental stuff.

Commented Jun 26, 2014 at 8:55

No, that's not possible since assigning it to a derived class reference would be like saying "Base class is a fully capable substitute for derived class, it can do everything the derived class can do", which is not true since derived classes in general offer more functionality than their base class (at least, that's the idea behind inheritance).

You could write a constructor in the derived class taking a base class object as parameter, copying the values.

Something like this:

public class Base < public int Data; public void DoStuff() < // Do stuff with data >> public class Derived : Base < public int OtherData; public Derived(Base b) < this.Data = b.Data; OtherData = 0; // default value >public void DoOtherStuff() < // Do some other stuff >> 

In that case you would copy the base object and get a fully functional derived class object with default values for derived members. This way you can also avoid the problem pointed out by Jon Skeet:

Base b = new Base();//base class Derived d = new Derived();//derived class b.DoStuff(); // OK d.DoStuff(); // Also OK b.DoOtherStuff(); // Won't work! d.DoOtherStuff(); // OK d = new Derived(b); // Copy construct a Derived with values of b d.DoOtherStuff(); // Now works! 
495 1 1 gold badge 3 3 silver badges 16 16 bronze badges answered Apr 8, 2009 at 11:36 Michael Klement Michael Klement 3,405 3 3 gold badges 32 32 silver badges 34 34 bronze badges

You could serialize the object to JSON and then deserialize it. Although strictly speaking, it is a no. You can use this "hacky" but simple and quick trick using JsonConvert .

var base = new BaseClass(); var json = JsonConvert.SerializeObject(base); DerivedClass derived = JsonConvert.DeserializeObject(json); 

An answer below implemented it as an extension method.

28k 17 17 gold badges 160 160 silver badges 177 177 bronze badges answered Jun 16, 2019 at 15:47 Jesse de gans Jesse de gans 1,617 1 1 gold badge 16 16 silver badges 27 27 bronze badges I answered this again below with extension methods. Yes, this is the answer. Commented Jun 25, 2020 at 22:05

public static T ConvertObject(this object myobj) < return Newtonsoft.Json.JsonConvert.DeserializeObjectNewtonsoft.Json.JsonConvert.SerializeObject(myobj)); >

Commented Jul 16, 2021 at 17:33

If Derived Class's has JsonRequired fields or JsonProperty that it for set PropertyName, it will not correct working

Commented Sep 25, 2021 at 8:01 GENIUS. This is a great answer, Thanks! Commented Feb 25, 2022 at 1:11

Depending of the properties It can cause errors likeNewtonsoft.Json.JsonSerializationException: Self referencing loop detected for property. Consider to pass new JsonSerializerSettings < ReferenceLoopHandling = ReferenceLoopHandling.Serialize >;

Commented Jan 6, 2023 at 0:17

I had this problem and solved it by adding a method that takes a type parameter and converts the current object into that type.

public TA As() where TA : Base < var type = typeof (TA); var instance = Activator.CreateInstance(type); PropertyInfo[] properties = type.GetProperties(); foreach (var property in properties) < property.SetValue(instance, property.GetValue(this, null), null); >return (TA)instance; > 

That means that you can use it in you code like this:

var base = new Base(); base.Data = 1; var derived = base.As(); Console.Write(derived.Data); // Would output 1 
answered May 3, 2014 at 14:43 Markus Knappen Johansson Markus Knappen Johansson 1,550 17 17 silver badges 22 22 bronze badges

You should use the type of the current class (base class) to get and set properties since those are the values you want to map over to the derived class.

Commented Aug 30, 2016 at 14:19

If you have properties that can't be written to in the derived type you should probably change to: if (property.CanWrite) property.SetValue(instance, property.GetValue(this, null), null);

Commented Sep 24, 2017 at 21:05

As many others have answered, No.

I use the following code on those unfortunate occasions when I need to use a base type as a derived type. Yes it is a violation of the Liskov Substitution Principle (LSP) and yes most of the time we favor composition over inheritance. Props to Markus Knappen Johansson whose original answer this is based upon.

This code in the base class:

 public T As() < var type = typeof(T); var instance = Activator.CreateInstance(type); if (type.BaseType != null) < var properties = type.BaseType.GetProperties(); foreach (var property in properties) if (property.CanWrite) property.SetValue(instance, property.GetValue(this, null), null); >return (T) instance; > 
 derivedObject = baseObect.As() 

Since it uses reflection, it is "expensive". Use accordingly.

answered Sep 17, 2016 at 6:30 1,718 1 1 gold badge 17 17 silver badges 23 23 bronze badges

I just tried this, and figured, it could be improved further, by overloading the explicit operator (and the implicit operator as well) .. but - the Compiler won't allow it: user-defined conversions to or from a base class are not allowed I see the reasons for this, but am disappointed, as it would have been so much fun if it did allow this..

Commented Oct 13, 2016 at 13:28

@MEC: I noticed you dropped the ` where T : MyBaseClass` part and added the if (type.BaseType != null) Statement relative to Markus Knappen Johansson 's A. Why is that? That means it would allow a Type in the Calls that's not Derived from MyBaseClass (or anything for that matter). I realize it'll still cause a compiler error if Assigned to myDerivedObject, but if it's just used as a Expression, it'll compile and at run-time just create a myDerivedObject without any data copied from "myBaseObject". I can't imagine an use case for that.

Commented Jan 24, 2018 at 21:17

@Tom, late reply, but thought it might still be useful. The best response to your question probably would be to say that the name "As" would better have been "AsOrDefault". Essentially we can take this result and compare it to a Default such as we do when using Linq's SingleOrDefault or FirstOrDefault.

Commented Jun 17, 2020 at 2:44

No it is not possible, hence your runtime error.

But you can assign an instance of a derived class to a variable of base class type.

answered Apr 8, 2009 at 11:14 17.1k 2 2 gold badges 29 29 silver badges 31 31 bronze badges

In c# 9.0 you can try to use records for this. They have default copy constructor that copy all fields - no need to use reflection / constructor with all fields.

public record BaseR < public string Prop1 < get; set; >> public record DerivedR : BaseR < public DerivedR(BaseR baseR) : base(baseR) < >public string Prop2 < get; set; >> var baseR = new BaseR < Prop1 = "base prob" >; var derivedR = new DerivedR(baseR) < Prop2 = "new prop" >; 

enter image description here

answered Jan 13, 2021 at 10:16 304 4 4 silver badges 9 9 bronze badges

As everyone here said, that's not possible directly.

The method I prefer and is rather clean, is to use an Object Mapper like AutoMapper.

It will do the task of copying properties from one instance to another (Not necessarily the same type) automatically.

answered Jan 7, 2013 at 20:36 Mahmood Dehghan Mahmood Dehghan 8,195 5 5 gold badges 55 55 silver badges 73 73 bronze badges

Not in the Traditional Sense. Convert to Json, then to your object, and boom, done! Jesse above had the answer posted first, but didn't use these extension methods which make the process so much easier. Create a couple of extension methods:

 public static string ConvertToJson(this T obj) < return JsonConvert.SerializeObject(obj); >public static T ConvertToObject(this string json) < if (string.IsNullOrEmpty(json)) < return Activator.CreateInstance(); > return JsonConvert.DeserializeObject(json); > 

Put them in your toolbox forever, then you can always do this:

var derivedClass = baseClass.ConvertToJson().ConvertToObject(); 

Ah, the power of JSON.

There are a couple of gotchas with this approach: We really are creating a new object, not casting, which may or may not matter. Private fields will not be transferred, constructors with parameters won't be called, etc. It is possible that some child json won't be assigned. Streams are not innately handled by JsonConvert. However, if our class doesn't rely on private fields and constructors, this is a very effective method of moving data from class to class without mapping and calling constructors, which is the main reason why we want to cast in the first place.

answered Jun 25, 2020 at 21:57 Patrick Knott Patrick Knott 1,811 19 19 silver badges 17 17 bronze badges

This does not do what OP asked. What you're doing is constructing a new object of the correct type for the variable, using data from the original object of the wrong type. This may or may not work, but either way, it is certainly not assigning an object of the base class type to a variable of the derived type.

Commented Jun 26, 2020 at 15:54

I answered the question: Is it possible to assign a base class object to a derived class reference with an explicit typecast? By saying no. I am providing an alternative that absolutely does work and is less confusing than generics. As denoted numerous times above, it can cause issues assigning to a derived class properties from a base class, however, this is exactly how it would work (and does in apis) if it were possible. Just because my answer can be used from a "wrong" type doesn't mean it cannot be used for a "right" type. @LasseV.Karlsen please retract your negative rating.

Commented Jun 29, 2020 at 20:11 Unlike most of the answers here that daisy chain JsonConverts, I show how to handle null as well. Commented Jun 29, 2020 at 20:45 Great addition to catch some edge cases :D Commented Jan 7, 2023 at 19:26

Just FYI, If you are using entity framework, you may have issues with converting to JSON. This may be because there is a circular reference due to virtual table references. If those child models also have a virtual reference to the parent, you can see where the circular reference exists. I figured since I gave a few gotchas, I'd append this one.

Commented Jul 5, 2023 at 16:02

Expanding on @ybo's answer - it isn't possible because the instance you have of the base class isn't actually an instance of the derived class. It only knows about the members of the base class, and doesn't know anything about those of the derived class.

The reason that you can cast an instance of the derived class to an instance of the base class is because the derived class actually already is an instance of the base class, since it has those members already. The opposite cannot be said.

answered Apr 8, 2009 at 11:16 30.3k 7 7 gold badges 80 80 silver badges 89 89 bronze badges

You can cast a variable that is typed as the base-class to the type of a derived class; however, by necessity this will do a runtime check, to see if the actual object involved is of the correct type.

Once created, the type of an object cannot be changed (not least, it might not be the same size). You can, however, convert an instance, creating a new instance of the second type - but you need to write the conversion code manually.

answered Apr 8, 2009 at 11:17 Marc Gravell Marc Gravell 1.1m 271 271 gold badges 2.6k 2.6k silver badges 2.9k 2.9k bronze badges

You have to use an object cloner/copier that will assign all the properties one by one.

Doing this by hand is inefficient and not future-proof. But serializing & deserializing to JSON and back is not the best solution, it is slow and very memory inefficient.

However, using AutoMapper is fast. PropMapper is even faster.

PS. Disclosure: I am a contributor at PropMapper open source project.

answered Oct 11, 2021 at 21:40 Alex from Jitbit Alex from Jitbit 58.8k 19 19 gold badges 196 196 silver badges 167 167 bronze badges

No, it is not possible.

Consider a scenario where an ACBus is a derived class of base class Bus. ACBus has features like TurnOnAC and TurnOffAC which operate on a field named ACState. TurnOnAC sets ACState to on and TurnOffAC sets ACState to off. If you try to use TurnOnAC and TurnOffAC features on Bus, it makes no sense.

answered Aug 25, 2014 at 11:09 Rohit Dodle Rohit Dodle 376 4 4 silver badges 13 13 bronze badges
class Program < static void Main(string[] args) < a a1 = new b(); a1.print(); >> class a < public a() < Console.WriteLine("base class object initiated"); >public void print() < Console.WriteLine("base"); >> class b:a < public b() < Console.WriteLine("child class object"); >public void print1() < Console.WriteLine("derived"); >> 

when we create a child class object,the base class object is auto initiated so base class reference variable can point to child class object.

but not vice versa because a child class reference variable can not point to base class object because no child class object is created.

and also notice that base class reference variable can only call base class member.

answered Sep 11, 2016 at 15:22 shatrudhan kumar shatrudhan kumar 21 4 4 bronze badges

There actually IS a way to do this. Think about how you might use Newtonsoft JSON to deserialize an object from json. It will (or at least can) ignore missing elements and populate all the elements that it does know about.

So here's how I did it. A small code sample will follow my explanation.

  1. Create an instance of your object from the base class and populate it accordingly.
  2. Using the "jsonconvert" class of Newtonsoft json, serialize that object into a json string.
  3. Now create your sub class object by deserializing with the json string created in step 2. This will create an instance of your sub class with all the properties of the base class.

This works like a charm! So.. when is this useful? Some people asked when this would make sense and suggested changing the OP's schema to accommodate the fact that you can't natively do this with class inheritance (in .Net).

In my case, I have a settings class that contains all the "base" settings for a service. Specific services have more options and those come from a different DB table, so those classes inherit the base class. They all have a different set of options. So when retrieving the data for a service, it's much easier to FIRST populate the values using an instance of the base object. One method to do this with a single DB query. Right after that, I create the sub class object using the method outlined above. I then make a second query and populate all the dynamic values on the sub class object.

The final output is a derived class with all the options set. Repeating this for additional new sub classes takes just a few lines of code. It's simple, and it uses a very tried and tested package (Newtonsoft) to make the magic work.

This example code is vb.Net, but you can easily convert to c#.

' First, create the base settings object. Dim basePMSettngs As gtmaPayMethodSettings = gtmaPayments.getBasePayMethodSetting(payTypeId, account_id) Dim basePMSettingsJson As String = JsonConvert.SerializeObject(basePMSettngs, Formatting.Indented) ' Create a pmSettings object of this specific type of payment and inherit from the base class object Dim pmSettings As gtmaPayMethodAimACHSettings = JsonConvert.DeserializeObject(Of gtmaPayMethodAimACHSettings)(basePMSettingsJson)