¿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.

Respuestas:


231
Action doNothing = () => { };

¿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);

10

Esto debería funcionar:

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

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).


2

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

¿No puedes simplemente hacer:

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.