如何检查C#lambda表达式是否为;空的;?

如何检查C#lambda表达式是否为;空的;?,c#,function,lambda,C#,Function,Lambda,大家好!假设我有一个函数,包含两个变量中的lambda表达式: DoSomething('a', x => { }); DoSomething('b', x => { Console.WriteLine(x); }) 在程序中,我需要根据表达式中的方法是否包含一些代码来执行一些操作。在我看来,它一定是这样的: public void DoSomething (char symbol, Action<string> execute) { if (

大家好!假设我有一个函数,包含两个变量中的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(...)
    }
public void DoSomething(字符符号,动作执行)
{
if(execute.Method.IsEmpty)
这(…)
其他的
多蒂(…)
}

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

您可以尝试查看操作的相应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(...)
    }
}
public void DoSomething(字符符号,动作执行)
{
字节[]体=execute.Method.GetMethodBody().GetILAsByteArray();
if((body.Length==1&&body[0]==42)| |(body.Length==2&&body[0]==0&&body[1]==42))
{
//0-无操作
//42-返回
这(…)
}
其他的
{
多蒂(…)
}
}

您可以尝试查看操作的相应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(...)
    }
}
public void DoSomething(字符符号,动作执行)
{
字节[]体=execute.Method.GetMethodBody().GetILAsByteArray();
if((body.Length==1&&body[0]==42)| |(body.Length==2&&body[0]==0&&body[1]==42))
{
//0-无操作
//42-返回
这(…)
}
其他的
{
多蒂(…)
}
}

似乎有两种不同的方法:

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

public void DoSomething (char symbol, Action<string> execute)
{
    if (execute == null) /* handle null case */ 
        DoThis()
    else 
        DoThat()
}
public void DoSomething(字符符号)
{
DoThis()
}
公共无效DoSomething(字符符号,动作执行)
{
if(execute==null)/*处理null大小写*/
DoThis()
其他的
DoThat()
}
另一个选项可以是可选参数(您应该以任何方式检查null):

public void DoSomething(字符符号,Action execute=null)
{
if(execute==null)
DoThis()
其他的
DoThat()
}

似乎有两种不同的方法:

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

public void DoSomething (char symbol, Action<string> execute)
{
    if (execute == null) /* handle null case */ 
        DoThis()
    else 
        DoThat()
}
public void DoSomething(字符符号)
{
DoThis()
}
公共无效DoSomething(字符符号,动作执行)
{
if(execute==null)/*处理null大小写*/
DoThis()
其他的
DoThat()
}
另一个选项可以是可选参数(您应该以任何方式检查null):

public void DoSomething(字符符号,Action execute=null)
{
if(execute==null)
DoThis()
其他的
DoThat()
}

这是不明智的,请改用DoSomething('a',null)。现在它很简单,传入的
操作
与任何其他函数都是一样的,您不应该知道它是做什么的。如果需要调用方提供
操作的一个路径
,以及调用方不提供任何内容的另一个路径,请提供不执行
操作
的方法重载。这是不明智的,请使用DoSomething('a',null')。现在它很简单,传入的
操作
与任何其他函数都是一样的,您不应该知道它是做什么的。如果您需要一个调用方提供
操作的路径
和另一个调用方不提供任何操作的路径,请提供一个不执行
操作
的方法重载。您不应该在IL达到峰值来做出代码决策。如果该操作调用了一个什么都不做的方法呢?你不能这么说。如果这个动作调用了一个什么都不做的方法,那么初始动作会做一些事情——它调用了一个方法:-)。同样,在发布模式下,如果调用的方法是空的,C编译器会直接优化它。我同意你的观点,这是非常脆弱的,但根据实际情况,不幸的是OP没有与我们分享,这可能是值得知道的。这是可怕的困难。您不应该在IL达到峰值来做出代码决策。如果该操作调用了一个什么都不做的方法呢?你不能这么说。如果这个动作调用了一个什么都不做的方法,那么初始动作会做一些事情——它调用了一个方法:-)。同样,在发布模式下,如果调用的方法是空的,C编译器会直接优化它。我同意你的观点,这是非常脆弱的,但根据实际情况,不幸的是OP没有与我们分享,这可能值得知道。