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

标签 c#

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

require(myStringVariable);

如果该值不满足某些要求,我只想显示一条消息。

是否还可以显示作为参数传递的变量(或表达式)的名称? (在 C++ 中,带有 stringize 运算符的宏可以完成这项工作。在 C# 中是否有任何等效工具或其他工具可以执行相同的操作?)

更新:我没有搜索类似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);
    }
}

最佳答案

基于this answer ,你可以像这样重写你的方法:

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

并写道

ERROR: Non empty value is required for the expression 'emptyString'.


请注意,上面的代码假设您只想检查字符串。如果不是这种情况,您可以使用签名 public static void RequireNotEmpty<T>(Expression<Func<T>> 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)}'.");
        }
    }

    ...
}

现在您可以使用Checker像这样的类:

public string DoStuff(Foo fooObj, string bar)
{
    Checker.RequireNotNull(() => fooObj);
    Checker.RequireNotEmpty(() => bar);

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

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

DoStuff(new Foo(), "");

消息

Non empty value is required for 'bar'.

写入控制台。

关于c# - 如何获取在 C# 中作为参数传递的表达式的字符串表示形式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50337945/

相关文章:

c# - WPF 将 IsEnabled 属性绑定(bind)到 List 的大小

c# - 检测两张图片是否相似

c# - 删除 rowDataBound 事件中的 Gridview 行 asp.net c#

c# - 如何解决?假设程序集引用 'System.Web.Mvc

c# - 将 PDF 合并在一起后如何解锁文件以进行删除

c# - 来自文件的 .NET Core IssuerSigningKey 用于 JWT 承载身份验证

c# - 在 C# 中使用 SixLabors.ImageSharp 裁剪和移动图片

c# - Guid:如何通过 LINQ to Entities 获取最新插入的记录?

c# - Web 服务调用后响应对象中的属性为空

c# - NuGet:在不创建引用的情况下复制 .DLL 文件?