Такая ситуация: определены несколько интерфейсов (например:
IMyInterface1, IMyInterface2, ...
). В классе
MyClass
есть свойство
IMyInterface MyProperty { get; set; }
.
Хотелось бы,
чтобы свойство реализовывало сразу два-три интерфейса (примерно как это может делать класс) без потери строгой типизации.
Насколько знаю — синтаксис C# это не позволяет. Создавать на каждую связку интерфейсов отдельный тип не хочется (получится слишком много комбинаций). Создавать связку свойств, каждое из которых реализует отдельный интерфейс — это тоже как-то криво.
Наследование интерфейсов предлагаю не обсуждать, так как это нехорошо (наследование — лишь эффектный способ избежать дублирования кода). Интерфейсы независимые.
Какие есть предложения?
interface IClickableButton
{
event Action Click;
}
interface IColorButton
{
Color Color { get; set; }
}
class MyForm
{
public IClickableButton ClickableButton { get; set; }
public IColorButton ColorButton { get; set; }
public <IClickableButton, IColorButton> ClickableColorButton { get; set; }
}
Есть два интерфейса: «НажимабельнаяКнопка» и «ЦветнаяКнопка». Я хочу, чтобы свойство «НажимабельнаяЦветнаяКнопка» класса «МояФорма» как-нибудь реализовывало сразу оба этих интерфейса.
Сейчас мне приходится делать два отдельных свойства. Как их объединить в одно? (код
<IColorButton, IColorButton> ClickableColorButton { get; set; }
не прокатит, это я для понятности написал)
P. P. S.:
В конечном итоге пришли к вопросу "
зачем это может быть нужно?" Согласен — задача редко встречающаяся. А
цель одна —
снижение взаимосвязи блоков кода.
Допустим, мы создаем классы-контроллеры, управляющие формами пользовательского интерфейса. Контроллеры работают не напрямую с классами, а через интерфейс. В большинстве случаев контроллеру достаточно подписываться на событие нажатия «НажимабельнойКнопки» и обрабатывать его. Но в один из двадцати контроллеров, например, не только обрабатывает клик, но и должен менять цвет этой кнопки. А еще пара контроллеров кроме клика должна менять текст на кнопке. Конечно, можно создать интерфейс сразу с «кликом», «цветом» и «текстом». Но ведь бОльшей части контроллеров остальные свойства вообще не нужны — им достаточно только клика. Вот и возникает задача — как бы передавать свойства «цвет» или «текст» только в тех редких случаях, когда они действительно необходимы.
И еще один момент — если код покрывается модульными тестами — в качестве подопытных объектов бывает нужно подсовывать mock-и. Чем проще интерфейсы, тем легче эти mock-объекты формировать.
Наверно, кто-то скажет что это уже излишнее абстрагирование, чересчур подробное — возможно… Но меня тут интересует — есть ли возможность. А в какой степени ее применять — это уже другой вопрос.
P. P. P. S.: подходящее для меня решение описано тут:
habrahabr.ru/blogs/net/123229 Пока писал топик, пользователь tenbits предложил точно такое же решение.