Czy istnieje sposób określenia „pustego” wyrażenia lambda w języku C #?


118

Chciałbym zadeklarować „puste” wyrażenie lambda, które nic nie robi. Czy istnieje sposób na zrobienie czegoś takiego bez konieczności stosowania DoNothing()metody?

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

private void DoNothing()
{
}

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

Moim zamiarem jest kontrolowanie tylko stanu włączenia / wyłączenia mojego polecenia WPF, ale to na bok. Może jest dla mnie po prostu za wcześnie rano, ale wyobrażam sobie, że musi istnieć sposób, aby po prostu zadeklarować x => DoNothing()wyrażenie lambda w taki sposób, aby osiągnąć to samo:

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

Czy jest jakiś sposób, aby to zrobić? Po prostu wydaje się niepotrzebne, aby potrzebować metody nie robienia niczego.

Odpowiedzi:


231
Action doNothing = () => { };

Czy istnieje predefiniowana pusta lambda? Myślę, że tworzenie pustej lambdy za każdym razem, gdy jej potrzebuję, jest złym pomysłem. Np. W JQuery jestnoop i spodziewałbym się, że coś podobnego będzie obecne w C #.
qqqqqqq

Czy więc wersja asynchroniczna tego wymaga gadatliwości Func<Task> doNothing = async() => await Task.CompletedTask;?
Patrick Szalapski

23

To stare pytanie, ale pomyślałem, że dodam kod, który okazał się przydatny w tego typu sytuacjach. Mam Actionsklasę statyczną i klasę Functionsstatyczną z kilkoma podstawowymi funkcjami:

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

Uważam, że to trochę poprawia czytelność:

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

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

10

To powinno działać:

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

7

Zakładając, że potrzebujesz tylko delegata (a nie drzewa wyrażeń), to powinno działać:

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

(To nie zadziała z drzewami wyrażeń, ponieważ ma treść instrukcji . Aby uzyskać więcej informacji, zobacz sekcję 4.6 specyfikacji języka C # 3.0).


2

Nie do końca rozumiem, dlaczego potrzebujesz metody DoNothing.

Nie możesz po prostu zrobić:

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

3
To jest prawdopodobnie sprawdzone i prawdopodobnie wyrzuci NRE.
Dykam

Myślę, że Dykam ma rację, ale po prostu nie myślałem o podaniu null :-)
Rob

1
Nie rozumiem, dlaczego jest to odrzucane? Jorge ma rację, chociaż sprawdzenie tego wymagałoby niewielkiego wysiłku.
Cohen,

+1, to jest poprawne rozwiązanie, wystarczy, że sprawdzanie wartości null powinno zostać rozszerzone new RelayCommand(...
nawfal,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.