Convert derived class to base class

86,805

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 and override stays in place;
  • name BaseClass is not used directly in the type cast, so if I introduce an intermediate MiddleClass in the hierarchy between BaseClass and DerivedClass, which also implements DoSomething(); then the MiddleClass'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();
Share:
86,805

Related videos on Youtube

Levitikon
Author by

Levitikon

Updated on July 09, 2022

Comments

  • Levitikon
    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
      Paul Tyng over 12 years
      Kind 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
      Levitikon over 12 years
      Ouch, I thought it would be something simple I overlooked. Thanks
    • Ani
      Ani over 12 years
  • Levitikon
    Levitikon over 12 years
    Thanks 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
    Levitikon over 10 years
    Deep copy is one of the acceptable solutions, but it comes at a performance cost.
  • Admin
    Admin over 9 years
    Are 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
    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
    Admin over 9 years
    @JonSkeet After reading the question carefully again I see what you mean.
  • Ashish-BeJovial
    Ashish-BeJovial about 8 years
    Hi, i am getting error in visual studio on your line
  • Vaibhav
    Vaibhav about 8 years
    Where 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
    Kasper Vesth about 8 years
    @Vaibhav It just ignores all the extra properties :)
  • Vaibhav
    Vaibhav about 8 years
    Ok, 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
    iGanja about 8 years
    All 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
    Shiloh over 7 years
    I 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
    ahjashish over 5 years
  • ahjashish
    ahjashish over 5 years
    Using 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
    Jon Skeet over 5 years
    @Loophole: Yup, new instead of override 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
    Neutrino over 4 years
    Your methods aren't virtual so this situation is not polymrphic and so not analogous to the original question.