0

I have two abstract classes

public abstract class PluginBase
{
    protected SettingBase LocalSettings { get; set; }
}

public abstract class SettingBase
{
}

I am then creating a new class using PluginBase, and along with it I create a class using SettingBase

public class MyPlugin : PluginBase
{

}

public class MySettings : SettingBase
{
    public string MyValue;
}

I then load an instance of "MySettings", into the "LocalSettings" property.

Within MyPlugin I would then like to access the "MyValue" property of the "LocalSettings" property. I know I can access it like this;

((MySettings)LocalSettings).MyValue;

But I am looking for a nicer way to do this, preferably without the need to constantly reference the new type every time, something like this;

MyLocalSettings.MyValue

I would ideally like to avoid referencing properties with any string based methods.

5
  • 2
    As a bizarre solution you could use dynamic property for LocalSettings :) Commented Jan 17, 2018 at 16:46
  • What does this mean? "I have two abstract classes that contain some base methods?" in this context every word means something, so I recommend being more literal. Are the methods virtual, abstract, or neither? Commented Jan 17, 2018 at 16:48
  • @ScottHannen The classes are fairly large, and contain a mixture of lots of things(Statics, abstracts, constant, etc), and they also inherit from another set of classes as well. I thought it best not to muddy the waters as it shouldn't impact a design pattern. Or would you disagree? Commented Jan 17, 2018 at 16:53
  • 2
    I just had a moment of disconnect when I started reading the question. This sort of question is all about the details, so it's a good idea to use very precise language. "I have two abstract classes that contain some methods," or "I have two abstract classes that contain some abstract | virtual methods." The addition of the word "base" is confusing if it doesn't actually mean something. (I'm almost splitting hairs.) Commented Jan 17, 2018 at 16:57
  • Not at all, you're totally right, even asking questions like this is full of pitfalls. I'll update to clarify :) Commented Jan 17, 2018 at 17:02

2 Answers 2

5

Could generics work for you maybe?

public abstract class PluginBase
{
    // move it to the generic base class
    // protected SettingBase LocalSettings { get; set; }
}

public abstract class PluginBase<TSettings> : PluginBase where TSettings : SettingBase
{
    protected TSettings LocalSettings { get; set; }
}

public abstract class SettingBase
{
}

public class MyPlugin : PluginBase<MySettings>
{
    public void DoIt()
    {
        Console.WriteLine(this.LocalSettings.MyValue);
    }
}

public class MySettings : SettingBase
{
    public string MyValue;
}
Sign up to request clarification or add additional context in comments.

1 Comment

I think generics are necessary. The only way to know that the settings class is a specific type, and therefore has a given property, is to declare it as that type. Any solution that results in assumptions or guesses about an object's type is a bad solution.
0

Just make SettingsBase actually contract anything than just emptiness:

public abstract class SettingBase
{
    public abstract object GetSettingValue( string settingName );
}

This imposes an obligation for the implementor

public class MySettings : SettingBase
{
    public override object GetSettingValue( string settingName )
    {
        switch (settingName) 
        {
            case "MySetting": ...

but gives a Chance to the client to use the obligation

this.LocalSettings.GetSettingValue( "MySetting" );

without any cast to specific implementation type.

2 Comments

I like that, and I actually use a similar solution elsewhere with an inherited base class that provides that functionality. However in this case, I want it strongly typed, not string based. Will update question to reflect this.
You can make consts out of strings so that the very same const is used both at the client and in the provider. That would be kind of "strongly" typed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.