Gibt es eine Möglichkeit, einen "leeren" C # -Lambda-Ausdruck anzugeben?

118

Ich möchte einen "leeren" Lambda-Ausdruck deklarieren, der nichts bewirkt. Gibt es eine Möglichkeit, so etwas zu tun, ohne die DoNothing()Methode zu benötigen ?

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

private void DoNothing()
{
}

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

Meine Absicht dabei ist es, nur den aktivierten / deaktivierten Status meines WPF-Befehls zu steuern, aber das ist eine Seite. Vielleicht ist es für mich einfach zu früh am Morgen, aber ich stelle mir vor, dass es eine Möglichkeit geben muss, den x => DoNothing()Lambda-Ausdruck einfach so zu deklarieren , um dasselbe zu erreichen:

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

Gibt es eine Möglichkeit, dies zu tun? Es scheint einfach unnötig, eine Do-Nothing-Methode zu benötigen.

rauben
quelle

Antworten:

231
Action doNothing = () => { };
Rauhotz
quelle
Gibt es ein vordefiniertes leeres Lambda? Ich denke, dass es eine schlechte Idee ist, jedes Mal, wenn ich es brauche, ein leeres Lambda zu erstellen. Zum Beispiel in JQuery gibt es dasnoop und ich würde erwarten, dass etwas Ähnliches in C # vorhanden ist.
qqqqqqq
Benötigt eine asynchrone Version davon die ausführliche Version Func<Task> doNothing = async() => await Task.CompletedTask;?
Patrick Szalapski
23

Dies ist eine alte Frage, aber ich dachte, ich würde Code hinzufügen, den ich für diese Art von Situation nützlich fand. Ich habe eine Actionsstatische Klasse und eine Functionsstatische Klasse mit einigen Grundfunktionen:

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

Ich glaube, dies trägt dazu bei, die Lesbarkeit ein wenig zu verbessern:

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

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

Das sollte funktionieren:

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

Angenommen, Sie benötigen nur einen Delegaten (anstelle eines Ausdrucksbaums), sollte dies funktionieren:

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

(Dies funktioniert bei Ausdrucksbäumen nicht, da es einen Anweisungshauptteil enthält . Weitere Informationen finden Sie in Abschnitt 4.6 der C # 3.0-Spezifikation.)

Jon Skeet
quelle
2

Ich verstehe nicht ganz, warum Sie eine DoNothing-Methode benötigen.

Kannst du nicht einfach tun:

SomeMenuCommand = new RelayCommand(
                null,
                x => CanSomeMenuCommandExecute());
Jorge Córdoba
quelle
3
Das ist wahrscheinlich überprüft und wird wahrscheinlich eine NRE werfen.
Dykam
Ich denke, Dykam hat Recht, aber ich habe einfach nicht daran gedacht, null zu bestehen :-)
Rob
1
Ich verstehe nicht, warum dies abgelehnt wird? Jorge macht einen gültigen Punkt, obwohl es eine kleine Anstrengung gewesen wäre, ihn zu überprüfen.
Cohen
+1, dies ist eine gültige Lösung, nur dass die Nullprüfung erweitert werden sollte new RelayCommand(...
Nawfal