【问题标题】:Is there a way to specify an "empty" C# lambda expression?有没有办法指定一个“空”的 C# lambda 表达式?
【发布时间】:2010-12-17 02:42:54
【问题描述】:

我想声明一个“空”的 lambda 表达式,它什么也不做。 有没有办法在不需要DoNothing() 方法的情况下做这样的事情?

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

private void DoNothing()
{
}

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

我这样做的目的只是控制我的 WPF 命令的启用/禁用状态,但这是一个旁白。也许对我来说早上太早了,但我想一定有一种方法可以像这样声明x => DoNothing() lambda 表达式来完成同样的事情:

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

有没有办法做到这一点?似乎不需要什么都不做的方法。

【问题讨论】:

    标签: c# lambda


    【解决方案1】:
    Action doNothing = () => { };
    

    【讨论】:

    • 是否存在预定义的空 lambda?我认为每次需要时创建一个空的 lambda 是一个坏主意。例如。在 JQuery there is the noop 中,我希望 C# 中会出现类似的东西。
    • 那么异步版本需要详细的Func<Task> doNothing = async() => await Task.CompletedTask;吗?
    【解决方案2】:

    我想我会添加一些我发现对这种情况有用的代码。我有一个 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);
    

    【讨论】:

    • 我希望我能再次投票!
    【解决方案3】:

    这应该可行:

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

    【讨论】:

      【解决方案4】:

      假设您只需要一个委托(而不是表达式树),那么这应该可以工作:

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

      (这不适用于表达式树,因为它有一个语句体。有关详细信息,请参阅 C# 3.0 规范的第 4.6 节。)

      【讨论】:

        【解决方案5】:

        我不完全明白你为什么需要一个 DoNothing 方法。

        你不能这样做:

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

        【讨论】:

        • 这可能已被检查并且可能会抛出 NRE。
        • 我认为 Dykam 是对的,但我只是没想过传递 null :-)
        • 我不明白为什么这被否决了? Jorge 提出了一个有效的观点,尽管要检查它会很费力。
        • +1,这是一个有效的解决方案,只是空检查应该在new RelayCommand(..中扩展。
        【解决方案6】:
        Action DoNothing = delegate { };
        Action DoNothing2 = () => {};
        

        我曾经将事件初始化为无操作操作,因此它不为空,如果在没有订阅的情况下调用它,它将默认为“无操作函数”而不是空指针异常。

        public event EventHandler<MyHandlerInfo> MyHandlerInfo = delegate { };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-20
          • 1970-01-01
          • 2023-03-26
          • 2013-02-26
          • 1970-01-01
          • 2014-08-25
          • 1970-01-01
          • 2023-03-30
          相关资源
          最近更新 更多