如何获取在c#中作为参数传递的表达式的字符串表示形式?

如何获取在c#中作为参数传递的表达式的字符串表示形式?,c#,C#,我有一个用于检查参数的静态方法 require(myStringVariable); 如果该值不符合某些要求,我只想显示一条消息 是否可以显示作为参数传递的变量(或表达式)的名称?在C++中,一个带有Srimige运算符的宏将完成这项工作。 更新:我没有搜索类似于nameof(myStringVariable)的内容。实际上,我想调用这个方法,如下所示: require(bareFname + ".ext"); 如果表达式不能通过检查,那么我将在方法内部执行如下操作 static void

我有一个用于检查参数的静态方法

require(myStringVariable);
如果该值不符合某些要求,我只想显示一条消息

是否可以显示作为参数传递的变量(或表达式)的名称?在C++中,一个带有Srimige运算符的宏将完成这项工作。 更新:我没有搜索类似于
nameof(myStringVariable)
的内容。实际上,我想调用这个方法,如下所示:

require(bareFname + ".ext");
如果表达式不能通过检查,那么我将在方法内部执行如下操作

static void required(... theExpressionArgument)
{
    string value = evaluate theExpressionArgument;
    if (value.Length == 0)
    {
        Console.WriteLine("ERROR: Non empty value is required for the expression "
                          + theExpressionArgument);
    }
}
基于,您可以这样重写您的方法:

public static void RequireNotEmpty(Expression<Func<string>> lambda)
{
    // Get the passed strings value:
    string value = lambda.Compile().Invoke();

    // Run the check(s) on the value here:
    if (value.Length == 0)
    {
        // Get the name of the passed string:
        string parameterName = ((MemberExpression) lambda.Body).Member.Name;

        Console.WriteLine($"ERROR: Non empty value is required for the expression '{parameterName}'.");
    }
}
string emptyString = "";
RequireNotEmpty(() => emptyString);
public string DoStuff(Foo fooObj, string bar)
{
    Checker.RequireNotNull(() => fooObj);
    Checker.RequireNotEmpty(() => bar);

    // Now that you checked the preconditions, continue with the actual logic.
    ...
}

错误:表达式“emptyString”需要非空值


注意,上面的代码假设您只想检查字符串。如果不是这样,您可以使用签名
publicstaticvoidrequirenotetry(表达式lambda)
,它将适用于任何类型
T

此外,我还将该方法重命名为更具可读性和意义的方法


编辑:推荐 读了你的评论后,我想这可能是你想要的:

public static class Checker
{
    private static T GetValue<T>(Expression<Func<T>> lambda)
    {
        return lambda.Compile().Invoke();
    }

    private static string GetParameterName<T>(Expression<Func<T>> lambda)
    {
        return ((MemberExpression) lambda.Body).Member.Name;
    }
   
    private static void OnViolation(string message)
    {
        // Throw an exception, write to a log or the console etc...
        Console.WriteLine(message);
    }

    // Here come the "check"'s and "require"'s as specified in the guideline documents, e.g.

    public static void RequireNotEmpty(Expression<Func<string>> lambda)
    {
        if(GetValue(lambda).Length == 0)
        {
            OnViolation($"Non empty value is required for '{GetParameterName(lambda)}'.");
        }
    }

    public static void RequireNotNull<T>(Expression<Func<T>> lambda) where T : class
    {
        if(GetValue(lambda) == null)
        {
            OnViolation($"Non null value is required for '{GetParameterName(lambda)}'.");
        }
    }

    ...
}
现在,当您使用无效参数调用
DoStuff
时,例如

DoStuff(new Foo(), "");
信息

“bar”需要非空值


您的意思是
nameof(variable)
?可能的重复我认为他不想要
nameof
,因为,如果他使用上述示例,但在
require
中,参数被称为
静态无效要求(字符串myStr)
它将输出
myStr
myStringVariable.
@SebastianHofmann:没有。我已经更新了问题来解释我需要什么。@BrootsWaymb:对不起,但我不认为它是重复的。至少,我看不出有什么相似之处。也许在C#中不可能做这样的事情。我明白了。总之,将字符串形式的表达式放入方法中的唯一方法是使其成为未编译的lambda表达式体。然后——在方法体内部——我可以编译传递的表示并调用它来获取值。同样,我仍然可以访问字符串表示。(在
MemberExpression
之前缺少一个开括号)是否有更好的方法将
lambda.Body
转换为外部写入的字符串?考虑编写
requirenoty(()=>myEmptyVariable+”)
@pepr是唯一的方法-有一种方法不使用昂贵的表达式,而是传递一个
Func
,但它依赖于IL解析,该解析只适用于简单引用(请参阅中的Reflect.cs文件)。我不确定您为什么要向字符串变量添加内容,但我很乐意进一步帮助您。你能告诉我更多你想要达到的目标吗?另外,谢谢你接受的答案,也谢谢你提到打字错误,我刚刚把它修好了。这个解决方案非常适合我。我只想传递一个变量。我只是好奇什么是可能的,什么不是。谢谢@pepr我不知道指南文件中说明了什么,但我编辑了我的答案,并添加了一个设计,我建议您进行
检查和
要求
。大致按照这种设计,您可以轻松创建可重用的参数检查。我希望我理解正确,这就是你想要实现的。这很好。谢谢。:)尽管如此,C#没有类似C++的宏仍然是一件微不足道的事情