У меня есть некоторые классы, наследовались существующему Windows Controls как TextBox и DateTimePicker.. и т.д.
Я хочу добавить пользовательские технические возможности для этих классов как (Чтение, Предупреждение... и т.д.), эти добавленные технические возможности являются тем же во всех этих классах
Проблема: эти классы, наследованные от различия, порождают, таким образом, я не могу поместить свои добавленные технические возможности в родительский класс,
Что является лучшей практикой в этом случае:
повторите код в каждом наследованном классе
Используйте разделенный класс, имеют технические возможности как Статические методы с параметром от интерфейса, реализуют этот интерфейс для классов и затем передают их.
Используйте разделенный класс как второй подход, но с Динамическим параметром (который добавил в C# 4.0),
или другой!!
Заранее спасибо
Я бы рассмотрел вариант 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 */ }
}
Если нужно, я бы, вероятно, создал методы расширения для каждого класса, а затем сослался бы на фактический код, необходимый для них, в каком-то другом объекте, который могут вызывать все методы расширения.
Таким образом, код не дублируется, а методы расширения делают вид, что методы должны быть в объекте.
По сути, это то же самое, создав статический метод и выполнив: Functions.DoSomething (my_Object);
Но мне всегда нравится: my_Object.DoSomething ()
лучше в объектно-ориентированном языке.
Я бы предложил определить интерфейс для поведения, а затем (чтобы не повторяться) создать методы расширения для этого определения интерфейса для ваших общих методов. (Вроде как ваш второй вариант, только с методами расширения вместо полностью статических методов).