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