Задать вопрос
Kalantyr
@Kalantyr

Множественное наследование в C# для свойств (или параметров функций)

Такая ситуация: определены несколько интерфейсов (например: 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 предложил точно такое же решение.
  • Вопрос задан
  • 9254 просмотра
Подписаться 3 Оценить 2 комментария
Ответ пользователя Shedal К ответам на вопрос (8)
Shedal
@Shedal
По-моему, вы не до конца продумали, как вы это хотите использовать. Вам же все равно прийдется создавать объект класса, который наследует оба интерфейса, а, значит, и создавать класс ColorClickableButton: IClickableButton, IColorButton.

В любом случае, вам, возможно, поможет конструкция типа этой:
public class MyForm<T> where T : IClickableButton, IColorButton
{
    T Button { get; set; }
}
Ответ написан