Реализовать объектный интерфейс только для чтения в C # - PullRequest
3 голосов
/ 17 декабря 2008

Моя цель - убедиться, что в большинстве сценариев объекты используются через «интерфейс только для чтения», который является подмножеством полного интерфейса.

  • Например, если бы я использовал C ++, я бы просто возвратил объект const.
  • В C #, если бы я мог добиться этого с помощью интерфейсов, я бы просто реализовал интерфейс только для чтения и использовал его везде. Однако мне нужна перегрузка операторов, что недопустимо для интерфейсов. Вот почему я должен использовать абстрактный базовый класс.
  • Но если я определю абстрактный базовый класс, мне не разрешено изменять доступность в производном типе.

Итак, как мне достичь своей цели в C #?

Ответы [ 4 ]

4 голосов
/ 17 декабря 2008

Как насчет того, чтобы поместить операции записи в интерфейс, а затем явно реализовать их в абстрактном базовом классе? Это не было бы на 100% идеальным решением (вы все равно могли бы привести объект к интерфейсу модификации), но по большей части это предотвратило бы случайный вызов модификационными методами.

3 голосов
/ 17 декабря 2008

Вам действительно нужна перегрузка оператора? Мы говорим о синтаксическом сахаре здесь. Кроме того, не все языки .NET используют перегрузку операторов одинаково. Таким образом, если вы используете перегрузку операторов, вы фактически делаете свой код специфичным для языка.

Я бы реализовал интерфейс только для чтения и отбросил бы требование перегрузки оператора.

2 голосов
/ 17 декабря 2008

Вы можете реализовать поведение readonly через состояние в объекте и выдать исключение, если вызывается модифицирующий метод?

1 голос
/ 17 декабря 2008

Если кому-то интересно, что я сделал, я, наконец, выбрал абстрактный интерфейс вместо интерфейса и скрыл метод в производном классе, чтобы получить правильные методы доступа:

Например, в базовом абстрактном классе (интерфейс только для чтения):

protected double accuracy;
public double Accuracy { get { return accuracy; } }

В производном классе:

public new double Accuracy
{
    get { return accuracy; }
    set { accuracy = value; }
}

Конечно, некрасиво с ключевым словом "new", но в этом случае оно подойдет мне.

...