【问题标题】:How to get the name of a parameter passed to a method?如何获取传递给方法的参数名称?
【发布时间】:2020-02-26 21:29:16
【问题描述】:

我目前有一个验证类,其中包含一个验证字符串不为空的方法(并记录信息,但这不是这里关心的问题)

protected void ValidateStringNotEmpty(string propertyName, string value)
{
    if (string.IsNullOrWhiteSpace(value))
    {
        ValidationErrors.Add($"Property [{propertyName}] must be filled");
    }
}

使用

调用
ValidateStringNotEmpty(nameof(Name), Name);

是否有一种简单(且经过优化)的方法来避免传递第一个参数 nameof(property) 的需要?

我看到了使用堆栈跟踪来跟踪回调的解决方案,但这似乎不是一个很好的解决方案...

编辑:我真正想做的是看看是否存在这样做(消除传递参数名称的需要)。我知道务实的解决方案是我已经使用的解决方案,这不是问题。

【问题讨论】:

标签: c# .net-core


【解决方案1】:

现在有“CallerArgumentExpression”随 dotnet 6 / C# 10 一起提供,完全符合您的要求

protected void ValidateStringNotEmpty(string value, [CallerArgumentExpression("value")] string propertyName = "")

【讨论】:

  • 谢谢,这正是我需要的!
【解决方案2】:

直接在属性内部验证并利用[CallerMemberName] 怎么样?

private string _text;

public string Text
{
    get => _text;
    set
    {
        if (IsValid(value))
        {
            _text = value;
        }
        else
        {
            ValidationErrors.Add("'abcd' was expected.");
        }
    }
}

private bool IsValid<T>(T value, [CallerMemberName] string propertyName = null)
{
    switch (propertyName)
    {
        case nameof(Text):
            return value as string == "abcd";
        default:
            throw new ArgumentOutOfRangeException(nameof(propertyName), propertyName, null);
    }
}

public static class ValidationErrors
{
    public static void Add(string message, [CallerMemberName] string propertyName = null)
    {
        throw new NotImplementedException();
    }
}

【讨论】:

  • 虽然这个解决方案很优雅,但我不希望在每次值更改时触发验证,只有在我调用它时才触发。谢谢 ! (顺便说一句,downvote 不是我的……)
  • 我不知道您是否使用 WPF,但它只允许在控件失去焦点时触发验证,而不是在属性发生更改时触发验证:docs.microsoft.com/en-us/dotnet/api/…
  • 不,它在一个简单的类库中,没有指向 GUI 或其他任何东西的链接
  • 设置一个无效值,然后设置一个有效值,不会清除验证错误。
  • 这只是一个例子,当然实际上还有很多事情要做。
猜你喜欢
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 2015-02-10
  • 2012-12-12
  • 1970-01-01
  • 2010-09-18
  • 2010-09-17
  • 2019-04-02
相关资源
最近更新 更多