Existe-t-il un moyen de spécifier une expression lambda C # «vide»?


118

Je voudrais déclarer une expression lambda "vide" qui ne fait rien. Existe-t-il un moyen de faire quelque chose comme ça sans avoir besoin de la DoNothing()méthode?

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

private void DoNothing()
{
}

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

Mon intention en faisant cela est de contrôler uniquement l'état activé / désactivé de ma commande WPF, mais c'est un aparté. Il est peut-être trop tôt le matin pour moi, mais j'imagine qu'il doit y avoir un moyen de simplement déclarer l' x => DoNothing()expression lambda d'une manière comme celle-ci pour accomplir la même chose:

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

Y a-t-il un moyen de faire cela? Il semble simplement inutile d'avoir besoin d'une méthode de ne rien faire.

Réponses:


231
Action doNothing = () => { };

Existe-t-il un lambda vide prédéfini? Je pense que c'est une mauvaise idée en termes de performances de créer un lambda vide à chaque fois que j'en ai besoin. Par exemple, dans JQuery, il y a lenoop et je m'attendrais à ce que quelque chose de similaire soit présent en C #.
qqqqqqq

Une version asynchrone de cela nécessite-t-elle donc le verbeux Func<Task> doNothing = async() => await Task.CompletedTask;?
Patrick Szalapski

23

C'est une vieille question, mais j'ai pensé ajouter du code que j'ai trouvé utile pour ce type de situation. J'ai une Actionsclasse statique et une Functionsclasse statique avec quelques fonctions de 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; }
}

Je pense que cela permet d'améliorer un tout petit peu la lisibilité:

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

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

10

Cela devrait fonctionner:

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

7

En supposant que vous n'avez besoin que d'un délégué (plutôt que d'un arbre d'expression), cela devrait fonctionner:

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

(Cela ne fonctionnera pas avec les arbres d'expression car il a un corps d'instruction . Voir la section 4.6 de la spécification C # 3.0 pour plus de détails.)


2

Je ne comprends pas tout à fait pourquoi vous avez besoin d'une méthode DoNothing.

Tu ne peux pas simplement faire:

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

3
Cela est probablement vérifié et lancera probablement un NRE.
Dykam

Je pense que Dykam a raison, mais je n'ai tout simplement pas pensé à passer null :-)
Rob

1
Je ne comprends pas pourquoi ce vote est défavorable? Jorge fait valoir un point valable, même si cela aurait été un petit effort pour le vérifier.
Cohen

+1, c'est une solution valide, juste que la vérification de null devrait être étendue dans new RelayCommand(...
nawfal
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.