Domanda

Ho il seguente classe che permette di alcuni oggetti abbonarsi a un evento di modifica. Il problema è che ho anche classi B, C e che hanno bisogno di questa funzionalità che consentono agli oggetti di sottoscrivere lo stesso tipo di cose. Noi certamente non vogliamo copiare e incollare questo comportamento.

Abbiamo considerato che eredita da una classe base comune, ma tutte le nostre classi tra cui A, B, e C già ereditare da una BaseClass comuni. E noi non vogliamo aggiungere questo comportamento a BaseClass perché le altre classi E, F, G che ereditano da BaseClass non hanno bisogno di questo comportamento.

C'è una soluzione migliore?

public class A : BaseClass
{

    /*other properties and code */

    public event EventHandler OnChange;
    private bool _hasChanged;
    public bool HasChanged
    {
        get { return _hasChanged; }
        set
        {
            _hasChanged = value;
            //only need to notify when we've changed.
            if (value)
            {
                if (OnChange != null)
                    OnChange(this, EventArgs.Empty);
            }
        }
    }
}
È stato utile?

Soluzione

Che cosa succede se non usiamo eredità per un momento?

1- Supponiamo che, invece di ereditare da una classe base comune, Comporre la classe client che richiede meccanismo di evento con un oggetto che implementa il meccanismo evento.

Supponiamo che la nostra classe è

 public class EventNotifier
{
    public event EventHandler OnChange;
    private bool _hasChanged;
    public bool HasChanged
    {
        get { return _hasChanged; }
        set
        {
            _hasChanged = value;
            //only need to notify when we've changed. 
            if (value)
            {
                if (OnChange != null)
                    OnChange(this, EventArgs.Empty);
            }
        }
    }
}

2 -

 public class A
{
    private EventNotifier eventNotifier;
    public EventNotifier MyEventNotifier { get { return eventNotifier; } }

    public A()
    {
        eventNotifier = new EventNotifier();
    }


}

3- Ora gli utenti di classe A (classe che viene ereditato / classe composto A)

questo è per se B contiene un

 public class b
{
    A obj ;
    public b()
    {
        obj = new A();
        obj.MyEventNotifier.OnChange += new EventHandler(delegate { Console.WriteLine("Hi"); });
        obj. MyEventNotifier.HasChanged = true;
    }
}

Altri suggerimenti

Si consideri un approccio di programmazione orientata agli aspetti, come quello utilizzato in questo esempio PostSharp . Essa permetterebbe di iniettare quel tipo di codice standard utilizzando attributi.

Se è stato creato l'aspetto del caso, si potrebbe quindi avere codice come:

public class A : BaseClass
{
    public event EventHandler OnChanged;

    [ChangedNotify("OnChanged")]
    public bool HasChanged { get; set; }
}

o, se l'idea è quella di avere un singolo evento OnChange per più proprietà, si può solo hard-code che nell'aspetto, riducendo il codice per

public class A : BaseClass
{
    [NotifyOnChanged]
    public bool HasChanged { get; set; }
}

Si potrebbe prendere in considerazione l'introduzione di una classe di intermediario tra BaseClass e A, B, C che contiene il comportamento comune. In questo modo non sarà inquinante E, F, G, che non hanno bisogno il comportamento.

             BaseClass
  -----------------------------
  |                           |
-----                   NotifyBaseClass
E,F,G                         |
                            -----
                            A,B,C

NB Anche se sembra AOP yummy ho avuto grossi problemi cercando di ottenere PostSharp al lavoro con altre tecnologie per esempio MS analisi del codice e MSBuild.

Avere una sottoclasse per gli oggetti notifyable potrebbe essere la strada da percorrere, ma può essere difficile con aspetti moltiplicando in questo modo in una vasta gamma di classi diverse. Un altro modo sarebbe per infatti includere nel vostro classe base e definire un'interfaccia per esso, allora si può semplicemente virare sull'interfaccia per le classi interessate.

Quando si esegue yous semplicemente controllare se si tratta di un IChangeable (o qualcosa) e solo collegare alla manifestazione poi

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top