У мене виникає проблема дизайну щодо властивостей .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
?