У меня возникла проблема дизайна, касающаяся свойств .NET.
interface IX
{
Guid Id { get; }
bool IsInvalidated { get; }
void Invalidate();
}
Проблема:
Этот интерфейс имеет два свойства только для чтения Id
и IsInvalidated
. Однако тот факт, что они доступны только для чтения, сам по себе не является гарантией того, что их значения останутся постоянными.
Скажем так, это было мое намерение прояснить, что ...
Id
представляет собой постоянное значение (которое, следовательно, может быть безопасно кэшировано), в то время какIsInvalidated
может изменить его значение в течение времени жизниIX
объекта (и поэтому не должно кэшироваться).
Как я могу изменить, interface IX
чтобы сделать этот контракт достаточно четким?
Мои собственные три попытки решения:
Интерфейс уже хорошо продуман. Наличие вызываемого метода
Invalidate()
позволяет программисту сделать вывод, чтоIsInvalidated
оно может повлиять на значение свойства с таким же именем .Этот аргумент верен только в тех случаях, когда метод и свойство имеют одинаковые имена.
Дополните этот интерфейс событием
IsInvalidatedChanged
:bool IsInvalidated { get; } event EventHandler IsInvalidatedChanged;
Наличие
…Changed
события дляIsInvalidated
состоянияId
означает, что это свойство может изменить его значение, а отсутствие аналогичного события для - это обещание, что это свойство не изменит свое значение.Мне нравится это решение, но это много дополнительных вещей, которые могут вообще не привыкнуть.
Замените свойство
IsInvalidated
методомIsInvalidated()
:bool IsInvalidated();
Это может быть слишком тонким изменением. Предполагается, что это намек на то, что значение вычисляется заново каждый раз, что не было бы необходимо, если бы оно было константой. В теме MSDN «Выбор между свойствами и методами» говорится следующее:
Используйте метод, а не свойство, в следующих ситуациях. […] Операция возвращает новый результат при каждом вызове, даже если параметры не меняются.
Какие ответы я ожидаю?
Меня больше всего интересуют совершенно разные решения проблемы, а также объяснение того, как они побеждают мои вышеупомянутые попытки.
Если мои попытки логически ошибочны или имеют существенные недостатки, о которых еще не говорилось, например, что остается только одно решение (или ни одного), я хотел бы услышать о том, где я ошибся.
Если недостатки незначительны и после принятия во внимание остается более одного решения, оставьте комментарий.
По крайней мере, я хотел бы получить отзыв о том, какое решение вы предпочитаете и по какой причине.
class Foo : IFoo { private bool isInvalidated; public bool IsInvalidated { get { return isInvalidated; } } public void Invalidate() { isInvalidated = true; } }
InvalidStateException
s, например, но я не уверен, возможно ли это даже теоретически. Хотя было бы неплохо.
IsInvalidated
нуженprivate set
?