2011-09-24 11 views
6

Entrambe queste classi contengono un'altra classe privata che genera eventi. Queste due classi poi ribadiscono questi eventi ai clienti.Come si refactoring due classi con gli stessi eventi duplicati?

Purtroppo, ciascuna delle due classi ha questo stesso codice esatto:

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); 
     } 
    } 
} 

Come potete vedere, devo ri-generare eventi da un oggetto privato. È ridondante. Ho provato ad utilizzare l'ereditarietà e l'immissione di questo codice duplicato in una classe base, ma continuo a ricevere errori come:

L'evento 'BaseClass.Foo' possono essere visualizzati solo sul lato sinistro del + = o - = (tranne quando utilizzato all'interno del tipo)

Qualcuno sa come sbarazzarsi di questo codice duplicato?

risposta

5

Che dire dell'esposizione degli eventi dell'oggetto privato come proprietà del wrapper? Come in,

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; 
} 

Se si ha familiarità con C# Proprietà probabilmente già sapete i get e set parole chiave. Le parole chiave add/remove sono fondamentalmente la stessa cosa, solo che vengono attivate quando si tenta di aggiungere o rimuovere un valore alla proprietà.

Quindi, quando si esegue il comando di (annullare) il proprio delegato su ExternalClass.SomeEvent, si sta effettivamente registrando (un) all'evento InternalClass.SomeEvent.

Se non si ha familiarità con le proprietà C#, http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx potrebbe essere di aiuto.

+2

È meglio che non usa OnEvent per il nome del vostro evento. OnEvent è il nome standard per il metodo di innalzamento/attivazione dell'evento. Altrimenti sono d'accordo con l'idea della tua risposta. –

+0

grazie mille per la correzione :) – Andrea

+0

Andrea: Grazie per la risposta! Sfortunatamente sto avendo un po 'di problemi a seguire esattamente cosa fa questo codice. Non ho mai nemmeno sentito parlare delle parole chiave 'add' e' remove 'o_O potresti spiegare questo codice un po '? –

0

Penso che questo funzionerà per voi. L'interfaccia pubblica consente a PrivateObject di rimanere interno. L'unico altro trucco è che RegisterIFooEvents deve essere chiamato nel costruttore.

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); 
    } 
} 

Prova di funzionamento in console app:

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); 
    } 
} 
Problemi correlati