0

Quick Example of the code

public class BaseSettings {}
public class SpecificSettings : BaseSettings {}
public class BaseClass
{
    public virtual BaseSettings Settings {get; set;}
    public void DoSomething(BaseSettings settings)
    {
        Settings = settings;
    }
}
public class InheritedClass : BaseClass
{
    public override SpecificSettings Settings {get; set;}
}

I have a number of classes inheriting BaseClass, and they all are going to have the identical "DoSomething" method. However, I want the derived class, SpecificSettings to the be the one that is set when it is called.

If I use this code, it will generate an error that tells me

'InheritedClass.Settings': type must be 'BaseSettings' to match overridden member 'BaseSettings.Settings'

I'm no OOP expert, but I thought an inherited class was a type of BaseSettings.

I've looked into doing this with generics, but it doesn't appear to meet my requirements, as at some point I need (during deserialization) to have a return type of a method be of type BaseClass.

D-Shih
  • 44,943
  • 6
  • 31
  • 51
EatATaco
  • 687
  • 7
  • 25
  • This can’t work because if it did you would be able to do the following: `BaseClass obj = new InheritedClass(); obj.Settings = new BaseSettings();`. This must not work because even though InheritedClass requires a SpecificSettings you could just assign a BaseSettings and thus violating the class contract. You can however do the following: in InheritedClass define a computer property which does all the conversions by writing `public SpecificSettings SpecificSettings { get => (SpecificSettings)Settings; set => Settings = value; }` – ckuri Aug 23 '18 at 20:29
  • [this post](https://stackoverflow.com/questions/35537666/override-child-class-inherited-property-with-more-derived-type) might also be a good candidate for a duplicate – Mong Zhu Aug 23 '18 at 20:38
  • What about an interface for the Settings and class implementations? That way you don't have to override the Property and just set it like `public ISettings Settings { get; set; }` – Ivan García Topete Aug 23 '18 at 22:33

2 Answers2

1

There is a virtual method in your BaseClass class

public virtual BaseSettings Settings { get; set; }

If your InheritedClass inheritance to BaseClass and want override Settings method, Settings Method signature need to the same as the base class.

public class InheritedClass : BaseClass
{
    public override BaseSettings Settings { get; set; }
}

but your override makes no sense because the Settings do the same thing as your base class.


I would create interface ISetting<T> with contract generics instead of inheritance BaseClass.

that you can use BaseClass and InheritedClass to implement ISetting<T> and decide which class use which setting.

If SpecificSettings extends the number properties in BaseSettings

I would create CommonProperty class to carry properties Because inheritance makes the class strongly coupled. use combination is more flexible than inheritance.

public class CommonProperty {
    // move your BaseClass common with SpecificSettings in here.
}

public interface ISetting<T>
    where T : BaseSettings
{

    T Settings { get; set; }
    void DoSomething(T settings);
}

public class BaseSettings { }
public class SpecificSettings : BaseSettings { }

public class BaseClass : ISetting<BaseSettings>
{
    public CommonProperty commonProperty { get; set; }

    public virtual BaseSettings Settings { get; set; }
    public void DoSomething(BaseSettings settings)
    {

        Settings = settings;
    }
}
public class InheritedClass : ISetting<SpecificSettings>
{
    public CommonProperty commonProperty { get; set; }
    public SpecificSettings Settings { get; set; }

    public void DoSomething(SpecificSettings settings)
    {
        Settings = settings;
    }
}
D-Shih
  • 44,943
  • 6
  • 31
  • 51
  • I appreciate the effort you put into the response. The issue is that I can't use a generic, because I need to pass the objects back from a function, so they need to be of the same type as the base class. I guess what I want to do is just impossible, so I'm just going to mark the functions abstract and make the inherited classes define them. – EatATaco Aug 24 '18 at 12:26
0

You can define an interface and call it ISetting where both BaseSetting and SpecificSetting implement that. Then, the type of Settings in both BaseClass and InheritedClass for the Settings would be ISetting Settings.

Homa F.
  • 41
  • 2
  • An interesting idea, and I'll explore it. However, the problem as it is now, is that SpecificSettings extends the number properties in BaseSettings. – EatATaco Aug 23 '18 at 20:52
  • That's fine. Let them both extend the ISettings. Because you need to have the same method signature in both base class and derived class when you are overriding a method. Then change the signature to public virtual ISettings Settings {get; set;} and public override ISettings Settings {get; set;} Then in the derived class return an instance of the SpecificSettings. – Homa F. Aug 23 '18 at 21:42