【问题标题】:How to check whether C# lambda expression is "empty"?如何检查 C# lambda 表达式是否为“空”?
【发布时间】:2017-03-05 16:32:25
【问题描述】:

大家好!假设我有一个函数,包含 2 个变体的 lambda 表达式:

DoSomething('a', x => { });
DoSomething('b', x => { Console.WriteLine(x); })

在程序的后面,我需要根据表达式中的方法是否包含一些代码来执行一些操作。在我看来,它必须看起来像这样:

 public void DoSomething (char symbol, Action<string> execute)
    {
        if (execute.Method.IsEmpty)
            DoThis(...)
        else 
            DoThat(...)
    }

但是,当然,我无法准确地写出这个。那么,如何检查函数中是否有命令呢?

【问题讨论】:

  • 这不明智,使用 DoSomething('a', null) 代替。现在很简单。
  • 传入的Action 与任何其他函数相同——您不应该知道它的作用。如果您需要一个调用者提供Action 的路径和另一个调用者不提供任何内容的路径,请提供一个不采用Action 的方法重载。

标签: c# function lambda


【解决方案1】:

似乎是两种不同的方法:

public void DoSomething (char symbol)
{
    DoThis()
}

public void DoSomething (char symbol, Action<string> execute)
{
    if (execute == null) /* handle null case */ 
        DoThis()
    else 
        DoThat()
}

另一个选项可能是可选参数(无论哪种方式,您都应该检查 null):

public void DoSomething (char symbol, Action<string> execute = null)
{
    if (execute == null)
        DoThis()
    else 
        DoThat()
}

【讨论】:

    【解决方案2】:

    你可以尝试查看action对应的IL:

    public void DoSomething(char symbol, Action<string> execute)
    {
        byte[] body = execute.Method.GetMethodBody().GetILAsByteArray();
        if ((body.Length == 1 && body[0] == 42) || (body.Length == 2 && body[0] == 0 && body[1] == 42))
        {
            // 0 - no op
            // 42 - return
            DoThis(...)
        }
        else
        {
            DoThat(...)
        }
    }
    

    【讨论】:

    • 这太可怕了。你不应该在 IL 上达到顶峰来做出代码决策。如果动作调用了一个什么都不做的方法呢?你不能这么说。
    • 如果动作调用了一个什么都不做的方法,那么初始动作会做一些事情——它调用一个方法:-) 还有可能在发布模式下,如果调用方法为空,C# 编译器将简单地优化它。我同意你的观点,这很脆弱,但取决于实际情况,不幸的是,OP 没有与我们完全分享,这可能值得了解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 2016-02-24
    • 2011-03-02
    • 1970-01-01
    相关资源
    最近更新 更多