2010-06-16 13 views
5

tengo algunas clases heredan de Windows ya existente controles como cuadro de texto y DateTimePicker, .etcCuál es la mejor práctica para la solución alternativa de Multi-Herencia en C#

Quiero añadir funcionalidades personalizadas para estas clases como (Lee, alerta, etc ...) estas funcionalidades añadidas son los mismos en todas estas clases

el problema es que estas clases heredados de los padres de diferencia así que no puedo poner mis funcionalidades añadidas en la clase padre,

¿Cuál es la mejor práctica en este caso?

  • repetición del código en cada uno heredado clase

  • utilizar una clase separada tiene los funcionalidades como métodos estáticos con el parámetro de una interfaz, implementar esta interfaz para las clases y pasan entonces ellos.

  • utilizar una clase separada como el segundo enfoque, pero con el parámetro dinámico (que añade en C# 4,0)

    u otro !!

Gracias de antemano

Respuesta

12

Consideraría la opción 4: composición.

Primero, defina su conjunto de funciones. Asumiremos que su lista parcial es exclusiva, por lo tanto, "Leer" y "Alertar".

En segundo lugar, cree una única clase que implemente esta funcionalidad, algo así como MyCommonControlBehaviors. Preferiría que esta implementación no sea estática si es posible, aunque puede ser genérica.

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

En tercer lugar, composición de uso para añadir una instancia de esta clase para cada uno de los tipos de controles personalizados y exponer esa funcionalidad a través de su control personalizado:

public class MyCustomControl 
{ 
    private MyCommonControlBehaviors common; // Composition 

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

Dependiendo de los detalles, puede ser creativo a el grado necesario Por ejemplo, quizás sus comportamientos personalizados necesiten interactuar con datos de control privados. En ese caso, haga que su control implemente una interfaz ICommonBehaviorHost común que sus comportamientos comunes necesitan.A continuación, pasar el control en la clase del comportamiento en la construcción como una instancia de 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 */ } 
} 
+4

y acóplelo con inyección de dependencia para minimizar el acoplamiento de su sistema ... –

+0

+1 @marc_s para la verdad. Hay muchas técnicas adicionales que se pueden usar para minimizar el acoplamiento y agregar capacidad a este enfoque. Una cosa que he hecho en el pasado es hacer 'MyCommonControlBehaviors' genérico para que pueda devolver un' MyCustomControl', sea lo que sea. (En este ejemplo, no tiene mucho sentido, pero en el dominio con el que estaba trabajando tenía mucho sentido). –

1

Si debe, lo que probablemente haría es crear métodos de extensión para cada clase y luego hacer referencia al código real necesario para estos en algún otro objeto que puedan llamar todos los métodos de extensión.

De esta manera, el código no está duplicado, y los métodos de extensión hacen que parezca que los métodos deben estar en el objeto.

Es esencialmente la misma mediante la creación de un método estático y haciendo: Functions.DoSomething(my_Object);

Pero siempre me gusta: my_Object.DoSomething() mejor en un lenguaje orientado a objetos.

0

Yo sugeriría que define una interfaz para los comportamientos, y luego (para no repetir siempre lo mismo) crear métodos de extensión en que la definición de la interfaz de tus métodos compartidos. (Algo así como su segunda opción, solo con métodos de extensión en lugar de métodos totalmente estáticos).

Cuestiones relacionadas