Search code examples
c#castingderived-classbase-class

Explicit cast of derived class to base class


I am trying to cast a derived class object to its base class (to save it via JSON conversion). Whenever I try to get the base class from the derived class object, it returns an object of the derived class. I am not able to get the base class object (tried using explicit and implicit casts as well as conversion).

public class PlanningListModel : INotifyPropertyChanged
{
    private DateTime _date;
    private List<PlanningEntryModel> _Plannings;
    private bool _isSaving = false;

    public List<PlanningEntryModel> Plannings {get=>_Plannings;} //field i want to serialize
    //Same declarations for public fields
}

public class PlanningListViewModel :PlanningListModel   INotifyPropertyChanged
{
    private DateTime _date;
    private List<PlanningEntryModel> _Plannings;
    private bool _isSaving = false;

    public List<PlanningEntryModel> Plannings{           
        get {
            if (App.Data == null || App.Data.User == null || App.Data.IsReplicating)
                return base.Plannings.FindAll(x => true);
            switch (App.Data.CurrentList) {
                case 0: return base.Plannings.FindAll(x => true);
                case 1: return base.Plannings.FindAll(x => x.Volonter.ID == App.Data.User.ID);
                case 2: return base.Plannings.FindAll(x =>  x.User.Referent==App.Data.User.ID);
                default: return base.Plannings.FindAll(x => true);
        }
    }
} 

What I am trying to do:

PlanningListViewModel A = new PlanningListViewModel ();
PlanningListModel B = (PlanningListModel)A;
typeof(B); // B stays PlanningListViewModel and not PlanningListModel

I need to access the field Plannings of the base class (because the Plannings field of the derived class is modified (overridden get)). Whenever I try to cast, the object stays a PlanningListViewModel object, I am unable to cast to its base class.

What am I doing wrong? I am thankful for any help!


Solution

  • I need to access the field Plannings of the base class (because the Plannings field of the derived class is modified (overridden get)).

    In your case it doesn't work because the property isn't virtual. You have to declare it like this:

    public class PlanningListModel : INotifyPropertyChanged
    {
        …
        public virtual List<PlanningEntryModel> Plannings {get=>_Plannings;}
    }
    

    And then override like this:

    public class PlanningListViewModel : PlanningListModel
    {
        …
        public override List<PlanningEntryModel> Plannings { … }
    }
    

    Then the call to B.Plannigs will work as you'd expect, i.e. invoking the getter declared in the PlanningListViewModel class.

    Whenever I try to cast, the object stays a PlanningListViewModel object, I am unable to cast to its base class.

    Yes, and that is by design. The following two lines are equivalent:

    PlanningListModel B = (PlanningListModel)A;
    PlanningListModel B = A;
    

    You see there's even no explicit cast needed. A cast does not change the type of an object (for the sake of completeness: in a rather rare custom overloaded conversion operator scenarios this is not true). It only affects how you view that object, i.e. what you see.