Доступ к свойствам базового класса в двойном производном классе

У меня проблемы с доступом к свойствам базового класса в двойном производном классе. Я включил простой пример моей проблемы ниже.

public class Device
{
   public Device(string status)
   {
      Status = status;
   }

   public string Status { get; set; }

   public void SetStatus(string value)
   {
      Status = value;
   }

   public string GetStatus()
   {
      return Status;
   }
}

public class Light : Device
{
   public Light(string status) : base(status)
   {
   }

   public void SetStatus(string value)
   {
      base.SetStatus(value)
   }

   public string GetStatus()
   {
      return Status;
   }
}

public class ColoredLight : Light
{
   public ColoredLight(string status) : base(status)
   {
   }

   public void SetStatus(string value)
   {
      base.SetStatus(value)
   }

   public string GetStatus()
   {
      return Status;
   }
}

// note: The derived classes also have some properties of their own, of course, 
// but they are not needed to illustrate the problem

Я знаю, что свойство Status базового класса определенно получает значение, но если я вызову метод GetStatus в классе ColoredLight, он вернет null.

Если я изменю функции GetStatus в классе Light и ColoredLight, чтобы они возвращали base.GetStatus(), он возвращает правильное значение. Однако я думал, что должна быть возможность доступа к свойствам базового класса непосредственно в производных классах. Я делаю что-то неправильно? Или это просто так надо делать?

Заранее спасибо за помощь.

edit: [Решено] Проблема, с которой я столкнулся, была связана с глупостью и недосмотром, поскольку я объявил свойство Status как в классе Device, так и в классе Light. Однако приведенные ниже решения улучшили мое понимание использования «защищенного», «виртуального» и «переопределения» в C #, поэтому я оставлю вопрос как есть, чтобы он мог помочь и другим!


person Joost    schedule 22.01.2014    source источник
comment
Разве вы не получаете предупреждения с этим кодом, поскольку вы не переопределяете методы SetStatus и GetStatus?   -  person LarsTech    schedule 22.01.2014
comment
Вы раньше программировали на Java, не так ли? Это не проблема, но ООП обычно пишется немного по-другому на С#. (без явного имени Get и Set)   -  person wondra    schedule 22.01.2014
comment
На самом деле я получаю предупреждение от Resharper о том, что я должен использовать новое ключевое слово, но код строится и вызывается правильный метод, поэтому я не думаю, что это вызывает здесь проблему. Хотя вы правы в том, что мне придется изменить и это.   -  person Joost    schedule 22.01.2014
comment
Во-первых, спасибо за помощь. Но, как я упоминал ниже, я думаю, что слишком сильно упростил код, поскольку мои фактические методы возвращают значения свойств, специфичные либо для производного класса, либо для одного из базовых классов, в зависимости от значения параметра. Таким образом, фактические методы несколько различаются в разных классах. Кроме того, перед возвратом методы также выполняют некоторую другую работу, поэтому я не могу просто использовать общедоступное свойство. Мой вопрос в основном сводится к следующему: почему значение Status равно null в производном классе, в то время как оно определенно установлено в базовом классе?   -  person Joost    schedule 22.01.2014


Ответы (1)


Избавьтесь от методов GetStatus() и SetStatus() вообще, это не java. вместо этого создайте свойство virtual и при необходимости переопределите его в классах-потомках.

public class Device
{
    public Device(string status)
    {
        this._status = status;
    }

    protected _status;
    public virtual string Status 
    { 
        get
        {
            return _status;
        }
        set
        {
            _status = value;
        }
    }
}

public class Light : Device
{
    public Light(string status) : base(status)
    {
    }
}

public class ColoredLight : Light
{
    public ColoredLight(string status) : base(status)
    {
    }

    public override string Status 
    { 
        get
        {
            return _status;
        }
        set
        {
            _status = value;
        }
    }
}
person Z..    schedule 22.01.2014
comment
На самом деле, возможно, я упростил проблему. Метод GetStatus() — это всего лишь пример. Фактический метод, который я использую, немного сложнее и в зависимости от значения параметра либо возвращает значение, характерное для производного класса, либо значение из одного из базовых классов. Теперь я попробовал это с методами, объявленными как virtual и override, но это не имеет значения. По какой-то причине я не могу напрямую получить доступ к свойству из базового класса в производных классах. Я могу получить к ним доступ только через какой-то base.GetProperty() метод. - person Joost; 22.01.2014
comment
Хорошо, я думаю, что моя точная проблема на самом деле была вызвана чем-то совершенно другим. В основном глупость с моей стороны, так как я случайно определил Status как в классе Device, так и в классе Light, и не видел его, пока не изменил код на ваше решение. Пример protected, virtual и override, который вы предоставили, очень помог мне, хотя и с пониманием того, как я могу улучшить свой код! Так что спасибо тебе! - person Joost; 22.01.2014