C'è un modo per specificare un'espressione lambda C # "vuota"?


118

Vorrei dichiarare un'espressione lambda "vuota" che non fa, beh, niente. C'è un modo per fare qualcosa di simile senza bisogno del DoNothing()metodo?

public MyViewModel()
{
    SomeMenuCommand = new RelayCommand(
            x => DoNothing(),
            x => CanSomeMenuCommandExecute());
}

private void DoNothing()
{
}

private bool CanSomeMenuCommandExecute()
{
    // this depends on my mood
}

Il mio intento in questo è solo controllare lo stato abilitato / disabilitato del mio comando WPF, ma questo è un a parte. Forse è solo troppo presto per me la mattina, ma immagino che ci debba essere un modo per dichiarare l' x => DoNothing()espressione lambda in qualche modo come questo per ottenere la stessa cosa:

SomeMenuCommand = new RelayCommand(
    x => (),
    x => CanSomeMenuCommandExecute());

C'è un modo per farlo? Sembra solo inutile aver bisogno di un metodo non fare nulla.

Risposte:


231
Action doNothing = () => { };

Esiste un lambda vuoto predefinito? Penso che sia una cattiva idea in termini di prestazioni creare un lambda vuoto ogni volta che ne ho bisogno. Ad esempio, in JQuery c'ènoop e mi aspetto che qualcosa di simile sia presente in C #.
qqqqqqq

Quindi una versione asincrona di questo richiede il verbose Func<Task> doNothing = async() => await Task.CompletedTask;?
Patrick Szalapski

23

Questa è una vecchia domanda, ma ho pensato di aggiungere del codice che ho trovato utile per questo tipo di situazione. Ho una Actionsclasse statica e una Functionsclasse statica con alcune funzioni di base:

public static class Actions
{
  public static void Empty() { }
  public static void Empty<T>(T value) { }
  public static void Empty<T1, T2>(T1 value1, T2 value2) { }
  /* Put as many overloads as you want */
}

public static class Functions
{
  public static T Identity<T>(T value) { return value; }

  public static T0 Default<T0>() { return default(T0); }
  public static T0 Default<T1, T0>(T1 value1) { return default(T0); }
  /* Put as many overloads as you want */

  /* Some other potential methods */
  public static bool IsNull<T>(T entity) where T : class { return entity == null; }
  public static bool IsNonNull<T>(T entity) where T : class { return entity != null; }

  /* Put as many overloads for True and False as you want */
  public static bool True<T>(T entity) { return true; }
  public static bool False<T>(T entity) { return false; }
}

Credo che questo aiuti a migliorare la leggibilità solo un po ':

SomeMenuCommand = new RelayCommand(
        Actions.Empty,
        x => CanSomeMenuCommandExecute());

// Another example:
var lOrderedStrings = GetCollectionOfStrings().OrderBy(Functions.Identity);

10

Questo dovrebbe funzionare:

SomeMenuCommand = new RelayCommand(
    x => {},
    x => CanSomeMenuCommandExecute());

7

Supponendo che sia necessario solo un delegato (anziché un albero delle espressioni), allora dovrebbe funzionare:

SomeMenuCommand = new RelayCommand(
        x => {},
        x => CanSomeMenuCommandExecute());

(Ciò non funzionerà con gli alberi delle espressioni poiché ha un corpo di istruzione . Vedere la sezione 4.6 delle specifiche C # 3.0 per maggiori dettagli.)


2

Non capisco completamente perché hai bisogno di un metodo DoNothing.

Non puoi semplicemente fare:

SomeMenuCommand = new RelayCommand(
                null,
                x => CanSomeMenuCommandExecute());

3
Probabilmente è selezionato e probabilmente genererà un NRE.
Dykam

Penso che Dykam abbia ragione, ma non ho pensato di passare il nulla :-)
Rob

1
Non capisco perché questo è downvoted? Jorge fa un punto valido, anche se sarebbe stato un piccolo sforzo verificarlo.
Cohen

+1, questa è una soluzione valida, solo che il controllo null dovrebbe essere esteso in new RelayCommand(...
nawfal
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.