Existe uma maneira de especificar uma expressão lambda C # “vazia”?

118

Eu gostaria de declarar uma expressão lambda "vazia" que faz, bem, nada. Existe uma maneira de fazer algo assim sem precisar do DoNothing()método?

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

private void DoNothing()
{
}

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

Minha intenção ao fazer isso é apenas controlar o estado ativado / desativado do meu comando WPF, mas isso é um aparte. Talvez seja muito cedo para mim, mas imagino que deve haver uma maneira de apenas declarar a x => DoNothing()expressão lambda de alguma forma como esta para realizar a mesma coisa:

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

Existe alguma maneira de fazer isso? Simplesmente parece desnecessário precisar de um método de não fazer nada.

Roubar
fonte

Respostas:

231
Action doNothing = () => { };
Rauhotz
fonte
Existe um lambda vazio predefinido? Acho que é uma má ideia em termos de desempenho criar um lambda vazio sempre que preciso. Por exemplo, em JQuery existe onoop e eu esperaria que algo semelhante estivesse presente em C #.
qqqqqqq
Então, uma versão assíncrona disso requer o verboso Func<Task> doNothing = async() => await Task.CompletedTask;?
Patrick Szalapski
23

Essa é uma pergunta antiga, mas pensei em adicionar algum código que achei útil para esse tipo de situação. Eu tenho uma Actionsclasse estática e uma Functionsclasse estática com algumas funções básicas:

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

Acredito que isso ajuda a melhorar um pouco a legibilidade:

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

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

Isso deve funcionar:

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

Supondo que você só precise de um delegado (em vez de uma árvore de expressão), isso deve funcionar:

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

(Isso não funcionará com árvores de expressão, pois tem um corpo de instrução . Consulte a seção 4.6 da especificação C # 3.0 para obter mais detalhes.)

Jon Skeet
fonte
2

Não entendo completamente por que você precisa de um método DoNothing.

Você não pode simplesmente fazer:

SomeMenuCommand = new RelayCommand(
                null,
                x => CanSomeMenuCommandExecute());
Jorge Córdoba
fonte
3
Isso provavelmente está marcado e provavelmente gerará um NRE.
Dykam de
Eu acho que Dykam está certo, mas eu simplesmente não pensei em passar null :-)
Rob
1
Eu não entendo por que isso foi rejeitado? Jorge faz uma afirmação válida, embora tivesse sido um pequeno esforço verificá-la.
Cohen,
+1, esta é uma solução válida, apenas que a verificação de nulos deve ser estendida em new RelayCommand(...
nawfal