2011-09-24 16 views
6

Ambas clases contienen otra clase privada que genera eventos. Estas dos clases luego vuelven a plantear estos eventos a los clientes.¿Cómo se refactorizan dos clases con los mismos eventos duplicados?

Por desgracia, cada una de las dos clases tiene este exactamente el mismo código:

public class FirstClass 
{ 
    public delegate void FooEventHandler(string foo); 
    public delegate void BarEventHandler(string bar); 
    public delegate void BazEventHandler(string baz); 

    public event FooEventHandler Foo; 
    public event BarEventHandler Bar; 
    public event BazEventHandler Baz; 

    private PrivateObject privateObject; 

    public FirstClass() 
    { 
     privateObject.Foo += FirstClass_Foo; 
     privateObject.Bar += FirstClass_Bar; 
     privateObject.Baz += FirstClass_Baz; 
    } 

    private void FirstClass_Foo(string foo) 
    { 
     if (Foo != null) 
     { 
      Foo(foo); 
     } 
    } 

    private void FirstClass_Bar(string bar) 
    { 
     if (Bar != null) 
     { 
      Bar(bar); 
     } 
    } 

    private void FirstClass_Baz(string baz) 
    { 
     if (Baz != null) 
     { 
      Baz(baz); 
     } 
    } 
} 

Como se puede ver, tengo que volver a subir los eventos de un objeto privado. Es redundante He intentado utilizar la herencia y la colocación de este código duplicado en una clase base, pero sigo recibiendo errores como:

El evento 'BaseClass.Foo' sólo puede aparecer en el lado izquierdo de + = o - = (excepto cuando utilizado desde dentro del tipo)

¿Alguien sabe cómo deshacerse de este código duplicado?

Respuesta

5

¿qué ocurre al exponer los eventos del objeto privado como propiedades de su contenedor? Al igual que en,

public class ExternalClass 
{ 
    private InternalClass _internalObject = new InternalClass(); 

    public event InternalClass.someDelegate SomeEvent 
    { 
     add 
     { 
      _internalObject.SomeEvent += value; 
     } 
     remove 
     { 
      _internalObject.SomeEvent -= value; 
     } 
    } 
} 

public class InternalClass 
{ 
    public delegate void someDelegate(string input); 
    public event someDelegate SomeEvent; 
} 

Si está familiarizado con C# Propiedades probablemente ya saben los get y set palabras clave. Las palabras clave add/remove son básicamente lo mismo, solo se activan cuando intenta agregar o quitar un valor a su propiedad.

Por lo tanto, cuando ordena (des) registrar su delegado al ExternalClass.SomeEvent, en realidad se está (des) registrando al evento InternalClass.SomeEvent.

Si no está familiarizado con las propiedades de C#, http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx lo ayudaría.

+2

es mejor que no usar OnEvent para el nombre de su evento. OnEvent es el nombre estándar para subir/disparar el evento del método. De lo contrario, estoy de acuerdo con la idea de tu respuesta. –

+0

muchas gracias por su corrección :) – Andrea

+0

Andrea: ¡Gracias por la respuesta! Lamentablemente, estoy teniendo problemas para seguir exactamente lo que hace este código. Nunca he oído hablar de las palabras clave 'add' y' remove' o_O ¿Podría explicar este código un poco? –

0

Creo que esto funcionará para usted. La interfaz pública permite que PrivateObject se mantenga interno. El único otro truco es que se debe llamar a RegisterIFooEvents en el constructor.

public interface IFooEvents 
{ 
    event BaseClass.FooEventHandler Foo; 
    event BaseClass.BarEventHandler Bar; 
    event BaseClass.BazEventHandler Baz; 
} 

internal class PrivateObject : IFooEvents 
{ 
    public event BaseClass.FooEventHandler Foo; 
    public event BaseClass.BarEventHandler Bar; 
    public event BaseClass.BazEventHandler Baz; 

    public void ChangeFoo(string foo) 
    { 
     if (Foo != null) 
     { 
      Foo(foo); 
     } 
    } 
} 

public abstract class BaseClass : IFooEvents 
{ 
    public delegate void BarEventHandler(string bar); 
    public delegate void BazEventHandler(string baz); 
    public delegate void FooEventHandler(string foo); 

    private IFooEvents _fooEvents; 

    public event FooEventHandler Foo 
    { 
     add { _fooEvents.Foo += value; } 
     remove { _fooEvents.Foo -= value; } 
    } 

    public event BarEventHandler Bar 
    { 
     add { _fooEvents.Bar += value; } 
     remove { _fooEvents.Bar -= value; } 
    } 

    public event BazEventHandler Baz 
    { 
     add { _fooEvents.Baz += value; } 
     remove { _fooEvents.Baz -= value; } 
    } 

    protected void RegisterIFooEvents(IFooEvents fooEvents) 
    { 
     _fooEvents = fooEvents; 
    } 
} 

public class FirstClass : BaseClass 
{ 
    private readonly PrivateObject _privateObject; 

    public FirstClass() 
    { 
     _privateObject = new PrivateObject(); 
     RegisterIFooEvents(_privateObject); 
    } 

    public void ChangeFoo(string foo) 
    { 
     _privateObject.ChangeFoo(foo); 
    } 
} 

Prueba de funcionamiento en aplicación de consola:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var class1 = new FirstClass(); 
     class1.Foo += EventRaised; 
     class1.ChangeFoo("TEST"); 

    } 

    static void EventRaised(string arg) 
    { 
     Console.WriteLine(arg); 
    } 
} 
Cuestiones relacionadas