Convert derived class to base class
Solution 1
You can't - that's entirely deliberate, as that's what polymorphism is all about. Suppose you have a derived class which enforces certain preconditions on the arguments you pass to an overridden method, in order to maintain integrity... you don't want to be able to bypass that validation and corrupt its internal integrity.
Within the class itself you can non-virtually call base.AnyMethod()
(whether that's the method you're overriding or not) but that's okay because that's the class itself deciding to potentially allow its integrity to be violated - presumably it knows what it's doing.
Solution 2
Although this sounds irrational but it works
DerivedClass B = new DerivedClass();
BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));
Solution 3
You absolutely CAN (call the base method), just read up on Polymorphism:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism
Example:
public class BaseClass
{
public void DoWork() { }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public new void DoWork() { }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
And how to call it:
DerivedClass B = new DerivedClass();
B.DoWork(); // This calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // This calls the old method.
Solution 4
Try using the new
keywor instead of override
As far as i know this should enable that desired behavior.
I'm not realy sure about that so please don't blame me if i'm wrong!
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public new void DoSomething()
{
Trace.Write("derived class");
}
}
Solution 5
The solutions with new
instead of override
break the polymorphism. Recently I came to the same problem and implemented it the following way. My solution has the following advantages:
virtual
andoverride
stays in place;- name
BaseClass
is not used directly in the type cast, so if I introduce an intermediateMiddleClass
in the hierarchy betweenBaseClass
andDerivedClass
, which also implementsDoSomething()
; then theMiddleClass
's implementation won't be skipped.
This is the implementation:
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
Trace.Write("derived class");
}
public void BaseDoSomething()
{
base.DoSomething();
}
}
The usage is:
DerivedClass dc = new DerivedClass();
dc.DoSomething();
dc.BaseDoSomething();
Related videos on Youtube
Levitikon
Updated on July 09, 2022Comments
-
Levitikon almost 2 years
I'm trying to refresh my memory but can't find answers with Google.
public class BaseClass { public virtual void DoSomething() { Trace.Write("base class"); } } public class DerivedClass : BaseClass { public override void DoSomething() { Trace.Write("derived class"); } }
If I create an instance of derived class, how do I convert it to it's base class so that when DoSomething() is called, it uses the base class's method only?
A dynamic cast still calls the derived class's overridden method:
DerivedClass dc = new DerivedClass(); dc.DoSomething(); (dc as BaseClass).DoSomething();
Output: "derived class"
-
Paul Tyng over 12 yearsKind of defeats the purpose of inheritance, typically in your override though you would manually invoke
base.DoSomething()
but barring that you may be able to do something with reflection. -
Levitikon over 12 yearsOuch, I thought it would be something simple I overlooked. Thanks
-
Ani over 12 yearspossible duplicate of How to invoke (non virtually) the original implementation of a virtual method?
-
-
Levitikon over 12 yearsThanks Jon. I want to make it clear, I very much enjoy and rely on the properties and methods of derived classes to be in effect even when the class is casted to it's base class. It would just be very nice also to strip away derived classes under certain special conditions. It looks like reflection or some sort of deep copy is the way to go.
-
Levitikon over 10 yearsDeep copy is one of the acceptable solutions, but it comes at a performance cost.
-
Admin over 9 yearsAre we sure this is the correct answer? Looks like you can call the base method if the derived class used the new keyword rather than overriding a virtual member of the base class.
-
Jon Skeet over 9 years@winnicki: At that point it's not the same situation as in the question. You could call the base class method if you didn't have the derived class method at all, or if it had a different name, or a different number of parameters etc...
-
Admin over 9 years@JonSkeet After reading the question carefully again I see what you mean.
-
Ashish-BeJovial about 8 yearsHi, i am getting error in visual studio on your line
-
Vaibhav about 8 yearsWhere does this put the extra properties that may be in the derived class when serializing into the base class? Eg. StudentDerived class introduced Height of student while inheriting from StudentBase.
-
Kasper Vesth about 8 years@Vaibhav It just ignores all the extra properties :)
-
Vaibhav about 8 yearsOk, but this kind of an anti-pattern should only be used -- though not justified -- when extending an exception or circumventing a situation. This kind of an OOP violation definitely calls for a design re-consideration.
-
iGanja about 8 yearsAll academic "anti-pattern" arguments aside, sometimes the easiest solution is the correct one. This solution works very nicely! Consider extending an entity model then trying to save the base entity after it is handed back from the client. This is a problem. Do you want to write tons of code extracting the base model, or just use this?
-
Shiloh over 7 yearsI agree it is kind of a round about way to do this, but in certain situations it may make sense. I had the exact situation iGanja mentions where the EF entity was extended, then needed to be sent back through code which updates the entity via EF.
-
ahjashish over 5 years
-
ahjashish over 5 yearsUsing new seems to be exactly what he is looking for. Remove virtual, pop in new instead of override and his code works exactly how he wants it to. How is it not the same situation as in the question?
-
Jon Skeet over 5 years@Loophole: Yup,
new
instead ofoverride
would indeed work, if the OP can do that. It's not entirely clear from the question whether it's about "what can I do with classes like this that I can't change" or "how can I change the classes themselves to behave in a different way". -
Neutrino over 4 yearsYour methods aren't virtual so this situation is not polymrphic and so not analogous to the original question.