Как объединить вложенные классы с аналогичными именами из производного и его базового класса - PullRequest
0 голосов
/ 19 февраля 2020

Я работал над небольшим проектом, в котором я создал стандартные реализации надстроек для системы. Эти стандартные реализации настраивают такие вещи, как ведение журнала, конфигурация и т. Д. c. все единообразно. Все с учетом удобства обслуживания и возможности повторного использования.

Теперь я сейчас борюсь с тем, как обрабатывать имена настроек. Прежде чем я всегда создавал вложенный класс Settings в с, я объявил некоторые константные строковые значения, такие как

public const string BananaSetting = "BananaSetting";

, так что я почти никогда не мог неправильно ввести имя параметра.

У меня, однако, есть базовый класс, который должен иметь параметр DEBUG для использования в качестве общего параметра c debug-enable; но также и параметры c, определенные для дополнения, которые существуют только для этого дополнительного модуля c. Поскольку я основываю каждый производный класс на классе, который имеет вложенный класс с настройкой DEBUG, любой производный класс, который пытается объявить похожий вложенный класс с именем Settings, вызовет предупреждение компилятора:

DerivedClass. Настройки скрывают унаследованный член 'BaseClass.Settings'. Используйте новое ключевое слово, если целью было скрытие.

Но я не хочу его скрывать. То, что я действительно хотел бы сделать, это объединить два класса настроек в один. Есть ли способ сделать это, или существует какой-то существующий шаблон проектирования, чтобы сделать это правильно?

public abstract class BaseClass
{
    public class Settings
    {
        public const string BananaSetting = "BananaSetting";
    }

    public abstract void BaseAbstractMethod();
    public void BaseMethod()
    {
        // intended use
        var settingValue = settingsDictionary[Settings.BananaSetting];
    }
}

public class DerivedClass : BaseClass
{
    public class Settings
    {
        public const string DerivedBananaSetting = "DerivedBananaSetting";
    }

    public override void BaseAbstractMethod()
    {
        // intended use
        var settingValue = settingsDictionary[Settings.BananaSetting];
        var subSettingValue = settingsDictionary[Settings.DerivedBananaSetting];
    }
}

Ответы [ 4 ]

1 голос
/ 19 февраля 2020

Вам нужно сделать класс настроек в производном классе new, потому что он имеет то же имя, что и в базовом классе. Чтобы иметь доступ к базовым настройкам в производном классе, вам также нужно наследовать вложенный класс настроек:

public class DerivedClass : BaseClass
{
    public new class Settings : BaseClass.Settings
    {
        public const string DerivedBananaSetting = "DerivedBananaSetting";
    }
// etc..

Остальная часть кода не изменяется.

0 голосов
/ 19 февраля 2020

Если я вас правильно понимаю, вы хотите расширить базовый класс еще несколькими настройками:

public class SettingBase
{
     public SettingDerived()
     {
         _settingNamesWithValues.Add("BananaSetting", new object());
     }

    private Dictionairy<string, object> _settingNamesWithValues = new Dictionairy<string, object>();

    public Dictionairy<string, object>() SettingNamesWithValues
    {
         get
         { 
            return _settingNameWithValue;
         }
    }
}

Производный класс:

public class SettingDerived : SettingBase
{
     public SettingDerived()
     {
         _settingNamesWithValues.Add("DerivedBananaSetting", new object());
     }

     private Dictionairy<string, object> _settingNamesWithValues = new Dictionairy<string, object>(); 

     //Hide the base SettingNamesWithValues, as we add the values to the derived collection anyways
     public new Dictionairy<string, object>() SettingNamesWithValues
     {
         get
         { 
            foreach(var keyValue in base.SettingNamesWithValues)
            {
                 _settingNameWithValue.Add(keyValue.Key, keyValue.Value);
            }                  
            return _settingNameWithValue;
         }
     }
}

После этого вы сможете получить доступ ко всем настройкам, используя свое имя.

var derived = new SettingsDerived();
var derivedBanana = derived.SettingNamesWithValues["DerivedBananaSetting"];
var banana = derived.SettingNamesWithValues["BananaSetting"];
0 голосов
/ 19 февраля 2020

Есть ли необходимость иметь их в подклассах? Вы можете легко достичь своей цели, сделав следующее:

public abstract class BaseClass
{
    public const string BananaSetting = "BananaSetting";

    public abstract void BaseAbstractMethod();
    public void BaseMethod()
    {
    }
}

public class DerivedClass : BaseClass
{
    public const string DerivedBananaSetting = "DerivedBananaSetting";

    public override void BaseAbstractMethod()
    {
    }
}
0 голосов
/ 19 февраля 2020

Как насчет чего-то? как это:

public abstract class SettingBase
{
     public abstract string GetSettingName();

     public abstract SettingBase GetSetting();

     //Shared Properties and Stuff here:
}

public class BananaSetting : SettingBase
{
     public override string GetSettingName()
     {
         return nameof(BananaSetting);
     }

     public override SettingBase GetSetting()
     {
         return this;
     }

     //Banana-Specific Settings go here
}

public class DEBUGSetting : SettingBase
{
     public override string GetSettingName()
     {
         return nameof(DEBUGSetting);
     }

     public override SettingBase GetSetting()
     {
         return this;
     }

     //DEBUG-Specific Settings go here
}


public class Program
{
     public void Demo()
     {
         var settings = LoadSettings();
         foreach(var setting in settings)
         {
             var implementation = setting.GetSetting();
             if(implementation is DEBUGSetting dbg)
             {
                 //access dbg.Properties here
             }
             [...]
         }
     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...