繁体   English   中英

我可以在不使用属性名称的情况下获取属性的 PropertyInfo 吗?

[英]Can I get PropertyInfo of a property without using its name?

我有一个具有属性的类,并且该属性具有一个attribute ,并且在该attributeget{}set{}中,我想访问该属性。

有没有办法做到这一点而不必将属性的名称作为string引用? 这行得通吗?

class MyClass
{
    [DefaultValue("This is my default")]
    public string MyProperty
    {
        get
        {
            string value = this.db.getMyProperty();
            if (value == null)
            {
                var myPropertyInfo = this.GetType().GetProperty("MyProperty");
                var myAttributeInfo = myPropertyInfo.GetCustomAttribute(
                    typeof (DefaultValueAttribute)) as DefaultValueAttribute;
                if (myAttributeInfo != null)
                    value = myAttributeInfo.defaultValue;
            }
            return value;
        }
    }
}

让我担心的是,传递属性名称违反了 DRY,并且很容易意外传递错误的字符串。

如何改进此代码以消除重复?

您没有说明您使用的是哪个版本的 Framework,但如果它是 .NET 4.5 或更高版本,您可以使用CallerMemberName 将以下方法添加到MyClass

private PropertyInfo GetProperty([CallerMemberName] string name = "")
{
   var myPropertyInfo = this.GetType().GetProperty(name);
   return myPropertyInfo;
}

然后,在MyProperty更改

var myPropertyInfo = this.GetType().GetProperty("MyProperty");

var myPropertyInfo = this.GetProperty();

在运行时,将自动为您提供GetProperty name参数的值。

实际上,如果你经常这样做(并且它总是相同的属性),你可以进一步简化它:

private string GetDefaultValueForProperty([CallerMemberName] string name = "")
{
    string defaultValue = null;
    var myPropertyInfo = this.GetType().GetProperty(name);
    var myAttributeInfo = myPropertyInfo.GetCustomAttribute<DefaultValueAttribute>();
    if (myAttributeInfo != null)
    {
        defaultValue = (string)myAttributeInfo.Value;
    }

    return defaultValue;
}

然后你的属性中的代码如下所示:

[DefaultValue("This is my default")]
public string MyProperty
{
    get
    {
        string value = this.db.getMyProperty();
        if (value == null)
        {
            value = GetDefaultValueForProperty();
        }
        return value;
    }
}

使用MethodBase.GetCurrentMethod()从方法或属性获取当前引用。 在您的情况下,使用Name属性,它将返回一个字符串get_MyProperty并删除带有substringget_部分,试试这个:

[DefaultValue("This is my default")]
public string MyProperty
{
    get
    {
        string value = this.db.getMyProperty();
        if (value == null)
        {
            // get property name from GetCurrentMethod.
            // use the SubString to remove the "get_" that comes from .net internals
            var propertyName = MethodBase.GetCurrentMethod().Name.Substring(4);

            // keep your method
            var myPropertyInfo = this.GetType().GetProperty(propertyName);
            var myAttributeInfo = myPropertyInfo.GetCustomAttribute(
                typeof (DefaultValueAttribute)) as DefaultValueAttribute;
            if (myAttributeInfo != null)
                value = myAttributeInfo.defaultValue;
        }
        return value;
    }
}

您可以使用这样的扩展方法:

public static TValue GetDefaultValue<TParent, TValue>
  (this TParent @this, Expression<Func<TParent, TValue>> e)
{
  var member = (e.Body as MemberExpression).Member;
  var attr = member.GetCustomAttribute(typeof (DefaultValueAttribute)) 
               as DefaultValueAttribute;

  return (TValue)attr.Value;
}

现在你只需要在你的财产中做到这一点:

return GetDefaultValue(i => i.MyProperty);

更好,并带有编译时检查,它也适用于重构 :)

扩展方法真的很简单,你希望它更安全,但想法应该很清楚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM