У меня есть интерфейс, хотя он также может быть абстрактным классом, который должен позволить его разработчикам указать, поддерживают ли они определенную функцию, и я ищу лучший способ достичь этого.Способы указать, поддерживается ли функция в контракте
Есть несколько вариантов здесь:
Глядя на BCL, я вижу, что Stream
класса имеет такие свойства, как CanRead
и CanSeek
, которые могут быть использованы для проверки, если функция поддерживается и бросает NotSupportedException
, если я то, что не поддерживается.
public interface IHandler
{
bool SupportsA { get; }
bool SupportsB { get; }
void A();
void B();
}
Это было бы подходящим подходом для меня, хотя у меня есть более , чем несколько функций, которые могут или не могут быть поддержаны, и я предпочитаю не определить свойство «SupportsX» для каждого из них.
Я тоже очень люблю ценностей побитовое Enum
, и я думаю, что другой путь был бы:
[Flags]
public enum HandlerFeature
{
None = 0
A = 1,
B = 2,
C = 4
}
public interface IHandler
{
HandlerFeature Features { get; }
void A();
void B();
void C();
}
И метод расширения, как это может быть написано:
bool Supports<T>(this T handler, HandlerFeature feature) where T : IHandler
Что я думаю также было бы намного красивее, чем другой подход, но я не мог не думать, что если каждое значение Enum
будет соответствовать члену в контракте, я должен иметь возможность отмечать эти элементы более явно. Тогда я подумал об атрибутах:
public interface IHandler
{
[HandlerRequires(Feature.None)]
HandlerFeature Features { get; }
[HandlerRequires(Feature.A)]
void A();
[HandlerRequires(Feature.B)]
void B();
[HandlerRequires(Feature.A | Feature.B)]
void AB();
[HandlerRequires(Feature.C)]
void C();
}
Хотя я не знаю, как использовать атрибут, как это во время выполнения, это, безусловно, делает определение интерфейса выглядит достаточно явный.
Есть ли передовая практика для этого?
Или другой подход, который вы рекомендуете?
Или что-то не так с теми, что я указал?
http://en.wikipedia.org/wiki/Interface_segregation_principle – Ani