И снова про множественное наследование((
using System.Windows.Forms;
namespace TestApp
{
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
namespace MyApp
{
<#
foreach(string T in new string[] { "Button", "TextBox", "Form" })
{
#>
public class <#=T#>E : <#=T#>
{
public object Tag1 { get; set; }
public object Tag2 { get; set; }
public object Tag3 { get; set; }
public delegate void MyEvent();
public MyEvent EVENT;
new public bool Visible
{
get
{
return (bool)this.Invoke((Func<bool>)(()=>base.Visible));
}
set
{
this.Invoke((Action)(()=>base.Visible=value));
}
}
}
<#
}
#>
}
}
После компиляции будет создаваться файл cs, в котором будет набор классов.
Конечно, не для всех случаев это подойдёт.
Опробовал в VS2010.
Увы, ни подсветки синтаксиса, ни автокомплита, ни интеллисенса... Так что стоит десять раз подумать, упростит ли это работу.
мне например даже сложно себе придумать ситуацию - что должно быть, что бы было необходимо множественное наследование. Практически все задачи - если внимательно к ним отнестись - обходятся полностью без него.
Еслиб это были все пользовательские классы, то да. тут можно. и то не всегда. А тут один класс стандартный.
Сделайте общий интерфейс, имплементируйте его во всех нужных классах, а в имплементации используйте вызов утилитной функции для обработки.
Вся "копипаста" сведется к копированию вызова функции.
Применить агрегацию или композицию.
Также посмотреть в сторону методов-расширений. Достаточно написать метод-расширение для базового класса, и он станет доступен в потомках.
Вообще, в современном C# есть хитрый способ реализовать множественное наследование на интерфейсах с реализацией (с помощью методов-расширений). Если любопытно, могу рассказать. Но сперва следует рассмотреть возможность применения агрегации или композиции.
Ну, не я один.
А то, что при обьявлении наследования нужно копипастить имя базового класса за двоеточие - вас не смущает?
Тоже знаете ли, далеко от идеала...
:-)
Ну если серьезно - зачем вам быть святее папы римского? Вы считаете, что копипаст в реальных проэктах не применяется?
Зло ведь не прием, а неправильное его использование.
Ну это пишут в учебниках. Но это прием, и он не запрещен. Вызов функции, во первых, может быть неизменным (стандартным )- как object + EventArg в обработчике эвентов, во вторых - даже если - изменить количество аргументов или их тип - это наиболее простое действие из из многих возможных.
Если вам действительно нужно множественное наследование, и дотнет - у вас не остается другого выбора.
Дотнет писали ребяты поумнее нас с вами, и если уж они что-то выкинули, значит нам же лучше.
:-)
Наконец-то. Хоть какая-то информация. Что за нубство, - не описывать сразу все необходимые условия?
Повторяю ещё раз:
- агрегация
- композиция
- методы-расширения
Приведите пример своего кода, что имеется, и что хочется. Покажите, что агрегация/композиция не подходят. В противном случае - я сочту, что общаюсь с нупом, и прекращу общение.
И, да, нет в C# множественного наследования! Нет! Разговор окончен.
PS хитрый финт ушами на интерфейсах с реализацией, о котором я упомянул, пока не привожу, ибо нефиг давать готовое невежливому ОПу.
Дотнет писали ребяты поумнее нас с вами, и если уж они что-то выкинули, значит нам же лучше.
Хочу позанудствовать.
Множественного наследования нет в языке C#. Но на платформе .NET реализовано множество разных языков, среди которых есть и языки с множественным наследованием. Например, Eiffel.
Выход: пишем библиотеку на таком языке, и используем её в C#.
class AddProp:Control
{
public object Tag1{get;set;}
public object Tag2{get;set;}
public object Tag3{get;set;}
public delegate void MyEvent();
public MyEvent EVENT;
new public bool Visible
{
get
{
return (bool)this.Invoke((Func<bool>)(()=>base.Visible));
}
set
{
this.Invoke((Action)(()=>base.Visible=value));
}
}
//и тд и тп, все это должно быть во всех классах
}
class ButtonE : Button, AddProp
{
}
class TextBoxE : TextBox, AddProp
{
}
class FormE : Form, AddProp
{
}
//и прочая куча контролов
То есть каждый контрол должен иметь набор свойств из первого класса
Ну так вам подсказали про композицию.
Делаете интерфейс, со свойством, которое возвращает некий класс (первый в вашей терминологии) , в этот класс пишите любой набор чего угодно,
и имплементируете этот интерфейс во всех Е контролах. :-)
(Ё мобиль строите?)
Потом любые изменения - только в "первом" классе Но он не должен быть сам контролом - чисто ваш класс, без иерархии.
Для того, чтобы вызывать методы и свойства TextBoxE, который и будет прямым наследником контрола, достаточно будет в методы первого класса передавать параметр типа Control. Вот и будет у них общая база.
В будущем никакого копипаста.
Менять свойста контрола.
Агрегацией конечно решить проблему можно, но придется для вызова свойств контрола прописывать еще класс перед свойством. А этого я делать не хочу.
Кстати видел когдато блог чей то, где один чел описал как он множественное наследование сделал в сишарпе. но это костыли дикие были.
Увы, только так и придётся делать. Я не вижу других способов для множественного наследования свойств.
Вероятно, можно исхитриться и сделать подобие МН с помощью АОП-фреймворков, но вряд ли это упростит проект, наверняка усложнит, и особенно его поддержку в будущем.
Насчёт хитрого множественного наследования. Есть такой способ:
interface IFoo { }
// Реализация методов интерфейса
static class Helper
{
public static void Foo(this IFoo foo)
{
Console.WriteLine("foo");
}
}
// Базовый класс, от которого будем наследоваться
class Base
{
public void Bar()
{
Console.WriteLine("bar");
}
}
// Это класс наследуется и от базового, и от интерфейса(ов).
// Причём методы интерфейса тоже реализованы!
class A : Base, IFoo { }
Однако, таким образом можно только методы реализовать. Свойства или поля не получится (их нужно пихать в базовый класс).