Domanda

Solo una domanda generale su quale sia la migliore pratica:

public void Foo()
{
    int x = 5;
    myControl.Click += (o, e) =>
    {
        x = 6;
    };
}

Nota, sto usando la variabile x all'interno del mio gestore eventi lambda.

O:

public class Bar
{
    private int x = 5;
    public void Foo()
    {
        Control myControl = new Control();
        myControl.Click += new EventHandler(myControl_Click);
    }

    private void myControl_Click(object sender, EventArgs e)
    {
        x = 6;
    }
}

Qui, x è un membro privato della classe, e quindi ho accesso ad esso nel mio gestore eventi.

Ora diciamo che non ho bisogno di x in qualsiasi altra parte del codice (per qualsiasi motivo), quale metodo è il modo migliore per andare?

È stato utile?

Soluzione

Dipende dalle tue necessità. Nel primo esempio, gli effetti collaterali del gestore eventi sono limitati all'ambito del metodo e, nel secondo, gli effetti collaterali hanno ambito istanza. Penso che l'uso di una chiusura in termini del tuo primo esempio non abbia alcuno scopo poiché X non viene utilizzato da nessuna parte, quindi è difficile determinare in base ai tuoi esempi.

Detto questo, è generalmente meglio trattare i gestori di eventi (che crei nel codice) come faresti con le variabili. Scoprili il più strettamente possibile e riformattali in un ambito più ampio, se necessario.

Un esempio migliore che evidenzia quando dovresti usare una chiusura è il seguente:

public void Subscribe(Action<string> messageCallBack)
{
    myButton.Click += () => messageCallBack("Button was clicked.");
}

Ciò consente a più abbonati ed è molto più semplice dell'alternativa:

private readonly List<Action<string>> callBacks;
public MyClass()
{
    callBacks = new List<Action<string>>();
    myButton.Click += myButton_Click;
}

private myButton_Click(object sender, EventArgs e)
{
    foreach (Action<string> callBack in callBacks)
    {
        callBack("Button was clicked");
    }
}

public void Subscribe(Action<string> messageCallBack)
{
    callBacks.Add(messageCallBack);
}

Altri suggerimenti

Se non hai bisogno di x in nessun'altra parte del codice, il tuo gestore è un no-op, quindi sicuramente è una situazione senza senso.

Una volta necessario hai bisogno di x, devi decidere se deve essere impostato sull'istanza Bar o sull'istanza del delegato (o possibilmente su una raccolta di delegati) e ciò determinerà ciò che fai.

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