Чи є спосіб вказати «порожній» вираз C # лямбда?


118

Я хотів би оголосити "порожній" лямбда-вираз, який нічого не робить. Чи є спосіб зробити щось подібне, не потребуючи DoNothing()методу?

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

private void DoNothing()
{
}

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

Мій намір робити це лише контролювати ввімкнений / відключений стан моєї команди WPF, але це вбік. Можливо, для мене просто занадто рано вранці, але я думаю, що повинен бути спосіб просто оголосити x => DoNothing()лямбдаський вираз таким чином, щоб здійснити те саме:

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

Чи є спосіб це зробити? Просто видається непотрібним потрібен метод нічого робити.

Відповіді:


231
Action doNothing = () => { };

Чи існує заздалегідь визначена порожня лямбда? Я думаю, що це погана ідея, коли мусить створити порожню лямбда щоразу, коли мені це потрібно. Наприклад, у JQuery є те,noop і я очікую, що щось подібне буде присутнє в C #.
qqqqqqq

Тож чи потрібна асинхронна версія цього слова Func<Task> doNothing = async() => await Task.CompletedTask;?
Патрік Шалапський

23

Це старе питання, але я думав, що я додам код, який вважаю корисним для подібного типу ситуації. У мене є Actionsстатичний клас і Functionsстатичний клас з деякими основними функціями в них:

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

Я вважаю, що це допомагає покращити читабельність лише невеликий шматочок:

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

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

10

Це має працювати:

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

7

Якщо припустити, що вам потрібен лише делегат (а не дерево виразів), то це має працювати:

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

(Це не працюватиме з деревами виразів, оскільки у нього є тіло оператора . Докладніше див. Розділ 4.6 специфікації C # 3.0.)


2

Я не повністю розумію, для чого потрібен метод DoNothing.

Ви не можете просто зробити:

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

3
Це, ймовірно, перевірено і, ймовірно, кине NRE.
Дікам

Я думаю, що Дікам прав, але я просто не замислювався над пропуском нуля :-)
Роб

1
Я не розумію, чому це спростовується? Хорхе робить вагомий пункт, хоча це було б невеликим зусиллям, щоб перевірити це.
Коен

+1, це правильне рішення, лише якщо слід перевірити нульову перевірку new RelayCommand(...
nawfal
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.