Получать доступ к свойству объекта без необходимости его приведения - PullRequest
2 голосов
/ 13 февраля 2012

У меня есть следующие три класса

public class Base
{
    string name;
}

public class Foo : Base
{
    int value;
}

public class Bar : Base
{
    double value;
}

Это то, что я пытаюсь

Base current = null;

if (somecondition)
    current = new Foo();
else
    current = new Bar();

for (int i=0; i<5; i++)
{
    current.value = i;           
}

Проблема в том, что VS 2010 показывает ошибку в теле цикла, поскольку Base не имеет свойства value.

Теперь я мог бы обойти эту проблему следующим образом:

Base current = null;
bool isBar = true;

if (somecondition)
{
    current = new Foo();
    isBar = false;
}
else
    current = new Bar();

for (int i=0; i<5; i++)
{
    if (isBar)
        (current as Bar).value = i;          
    else
        (current as Foo).value = i;
}

Но я надеялся на лучшее решение, потому что как только цикл начинает итерацию, тип current не изменится, но я собираюсь протестировать тип и, соответственно, привести его к каждой итерации.

Каков был бы правильный способ сделать это?

Ответы [ 3 ]

2 голосов
/ 13 февраля 2012

После того, как вы сделаете поля доступными (или выставите их в качестве доступных свойств), вы можете выбрать:

  • Сделайте ваш базовый класс абстрактным, используя абстрактный метод или свойство для установки значения (и, возможно, его возврата) - проблема здесь в том, что вы не можете легко сделать это, когда два типа различаются
  • Создайте интерфейс, чтобы сделать то же самое, и приведите к интерфейсу
  • Просто разыграйте, как вы сейчас
  • Используйте dynamic, если вы используете C # 4 - просто объявите current как dynamic, и вы можете присвоить current.value, и компилятор вставит код для его обработки во время выполнения
  • Переработать ваш код / ​​иерархию наследования

Лично я бы, по крайней мере, рассмотрел последний подход - уместно ли здесь наследование? Действительно ли два типа для value должны быть разными? Имеют ли они одинаковое значение , означающее , и если да, имеет ли смысл передавать значение в базовый класс и, возможно, сделать его универсальным, если вам нужны разные типы?

0 голосов
/ 13 февраля 2012

Во-первых, ваши поля "значения" не отображаются как открытые.

Во-вторых, я не думаю, что вы не избежите явного приведения здесь.Просто представьте, что ваш класс Бар выглядит так:

   public class Bar : Base
   {
    public string value;
   }
0 голосов
/ 13 февраля 2012

Вы можете вместо использования базового класса создать интерфейс со значением Value в качестве свойства, а затем использовать Foo и Bar для реализации этого интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...