¿Hay alguna forma de especificar una expresión lambda C # "vacía"?

118

Me gustaría declarar una expresión lambda "vacía" que no hace, bueno, nada. ¿Hay alguna forma de hacer algo como esto sin necesitar el DoNothing()método?

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

private void DoNothing()
{
}

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

Mi intención al hacer esto es solo controlar el estado habilitado / deshabilitado de mi comando WPF, pero eso es un aparte. Tal vez sea demasiado temprano para mí, pero imagino que debe haber una manera de declarar la x => DoNothing()expresión lambda de alguna manera como esta para lograr lo mismo:

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

Hay alguna manera de hacer esto? Simplemente parece innecesario necesitar un método de no hacer nada.

Robar
fuente

Respuestas:

231
Action doNothing = () => { };
Rauhotz
fuente
¿Existe una lambda vacía predefinida? Creo que es una mala idea en cuanto al rendimiento crear un lambda vacío cada vez que lo necesito. Por ejemplo, en JQuery existenoop y esperaría que algo similar esté presente en C #.
qqqqqqq
Entonces, ¿una versión asíncrona de esto requiere el detallado Func<Task> doNothing = async() => await Task.CompletedTask;?
Patrick Szalapski
23

Esta es una pregunta antigua, pero pensé que agregaría algún código que encontré útil para este tipo de situación. Tengo una Actionsclase estática y una Functionsclase estática con algunas funciones básicas en ellas:

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

Creo que esto ayuda a mejorar la legibilidad solo un poquito:

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

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

Esto debería funcionar:

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

Suponiendo que solo necesita un delegado (en lugar de un árbol de expresión), esto debería funcionar:

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

(Eso no funcionará con árboles de expresión, ya que tiene un cuerpo de declaración . Consulte la sección 4.6 de la especificación C # 3.0 para obtener más detalles).

Jon Skeet
fuente
2

No entiendo del todo por qué necesita un método DoNothing.

¿No puedes simplemente hacer:

SomeMenuCommand = new RelayCommand(
                null,
                x => CanSomeMenuCommandExecute());
Jorge Córdoba
fuente
3
Eso probablemente esté verificado y probablemente arroje un NRE.
Dykam
Creo que Dykam tiene razón, pero no pensé en pasar null :-)
Rob
1
No entiendo por qué se vota negativamente. Jorge hace un punto válido, aunque habría sido un pequeño esfuerzo comprobarlo.
Cohen
+1, esta es una solución válida, solo que la verificación nula debe extenderse new RelayCommand(...
nawfal