Какова лучшая практика для альтернативного решения Multi-Inheritance в C # - PullRequest
5 голосов
/ 16 июня 2010

У меня есть некоторые классы, наследуемые от существующих элементов управления Windows, таких как TextBox и DateTimePicker, ..etc

Я хочу добавить пользовательские функции для таких классов, как (Read, Alert и т. Д.) эти дополнительные функции одинаковы во всех этих классах

Проблема в том, что эти классы унаследованы от разностных родителей, поэтому я не могу добавить свои дополнительные функции в родительский класс,

Какая лучшая практика в этом случае:

  • повторение кода в каждом унаследованном класс

  • Используйте отдельный класс, у которого есть функциональные возможности как статические методы с параметром из интерфейса, реализовать этот интерфейс для классов и затем передайте их.

  • Используйте отдельный класс, как при втором подходе, но с параметром Dynamic (который добавлен в C # 4.0)

    или другое !!

Заранее спасибо

Ответы [ 4 ]

12 голосов
/ 16 июня 2010

Я бы рассмотрел вариант 4: композиция.

Сначала определите ваш набор функций.Мы предполагаем, что ваш частичный список является эксклюзивным, поэтому «Чтение» и «Предупреждение».

Во-вторых, создайте отдельный класс, реализующий эту функцию, что-то вроде MyCommonControlBehaviors.Я бы предпочел, чтобы эта реализация не была статичной, если это возможно, хотя она может быть общей.

public MyCommonControlBehaviors
{
    public Whatever Read() { /* ... */ }
    public void Alert() {}
}

В-третьих, используйте композицию, чтобы добавить экземпляр этого класса к каждому из ваших пользовательских типов элементов управления и предоставить эту функциональность.с помощью пользовательского элемента управления:

public class MyCustomControl
{
    private MyCommonControlBehaviors common; // Composition

    public Whatever Read() { return this.common.Read(); }
    public void Alert() { this.common.Alert(); }
}

В зависимости от специфики вы можете проявить творческий подход до необходимой степени.Например, возможно, ваши пользовательские поведения должны взаимодействовать с частными данными управления.В этом случае заставьте свой элемент управления реализовывать общий ICommonBehaviorHost интерфейс, необходимый для вашего общего поведения.Затем передайте элемент управления в класс поведения при создании как экземпляр ICommonBehaviorHost:

public interface ICommonBehaviorHost
{
    void Notify();
}

public class MyCommonControlBehaviors
{
    ICommonBehaviorHost hst = null;

    public MyCommonControlBehaviors(ICommonBehaviorHost host) 
    {
        this.hst = host;
    }

    public void Alert() { this.hst.Notify(); }  // Calls back into the hosting control
    // ...
}

public class MyCustomControl : ICommonBehaviorHost
{
    private MyCommonControlBehaviors common = null;

    public MyCustomControl() { common = new MyCommonControlBehaviors(this); }
    public Whatever Read() { return this.common.Read(); }
    public void Alert() { this.common.Alert(); }

    void ICommonBehaviorHost.Notify() { /* called by this.common */ }
}
6 голосов
/ 16 июня 2010
1 голос
/ 16 июня 2010

Если вам нужно, то, вероятно, я бы создал методы расширения для каждого класса, а затем ссылался на фактический код, необходимый для них, в каком-то другом объекте, который могут вызывать все методы расширения.не дублируются, а методы расширения делают вид, что методы должны быть в объекте.

По сути, это то же самое, создав статический метод и выполнив: Functions.DoSomething(my_Object);

Но мне всегда нравится: my_Object.DoSomething() лучше на языке OO.

0 голосов
/ 16 июня 2010

Я бы предложил определить интерфейс для поведения, а затем (чтобы не повторяться) создать методы расширения для этого определения интерфейса для ваших общих методов.(Вроде как ваш второй вариант, только с методами расширения вместо полностью статических методов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...