获取给定其名称的属性的默认值



我有一个属性,(示例如下所示)。

 [DefaultValue(false)]
 public bool MyProperty {
    get {
       return myVal;
    }
    set {
       myVal=value;
    }
 }

我使用它的情况是确保如果未设置默认值,它在 PropertyGrid 中显示为粗体

发现在我的构造函数中,我必须设置我的属性的初始值,并希望它们匹配,这非常烦人。

是否可以让我的构造函数"发现"给定属性的默认值,并相应地对其进行设置? 像这样:

myctor()
{
   myVal = GetDefaultValueProperty<bool>("MyProperty");
}

可以使用以下代码获取所需的元数据。

public static T GetDefaultValue<T>(string propertyName)
{
    var property = typeof(MyClass).GetProperty(propertyName);
    var attribute = property
        .GetCustomAttribute(typeof(DefaultValueAttribute)) 
            as DefaultValueAttribute;
    if(attribute != null)
    {
        return (T)attribute.Value;
    }
}

如果你想做一些非常酷的事情,你可以使用 Lambda 表达式来做到这一点:

public static T GetDefaultValue<T>(
    Expression<Func<T, MyClass>> propertySelector)
{
    MemberExpression memberExpression = null;
    switch (expression.Body.NodeType)
    {
        case ExpressionType.MemberAccess:
            // This is the default case where the 
            // expression is simply member access.
            memberExpression 
                = expression.Body as MemberExpression;
            break;
        case ExpressionType.Convert:
            // This case deals with conversions that 
            // may have occured due to typing.
            UnaryExpression unaryExpression 
                = expression.Body as UnaryExpression;
            if (unaryExpression != null)
            {
                memberExpression 
                    = unaryExpression.Operand as MemberExpression;
            }
            break;
    }

    MemberInfo member = memberExpression.Member;
    // Check for field and property types. 
    // All other types are not supported by attribute model.
    switch (member.MemberType)
    {
        case MemberTypes.Property:
            break;
        default:
            throw new Exception("Member is not property");
    }
    var property = (PropertyInfo)member;
    var attribute = property
        .GetCustomAttribute(typeof(DefaultValueAttribute)) 
            as DefaultValueAttribute;
    if(attribute != null)
    {
        return (T)attribute.Value;
    }
}

用法是:

myctor()
{
   myVal = GetDefaultValue(x => x.MyProperty);
}

可以调用 GetProperty 方法来查找属性,然后调用 GetCustomAttributes(typeof(DefaultValueAttribute)(并强制转换其结果)来应用属性。

这是一个基于 Paul Turner 答案的通用扩展方法。它将适用于任何类的任何成员。

public static bool TryGetDefaultValue<TSource, TResult>(this TSource _, Expression<Func<TSource, TResult>> expression, out TResult result)
{
    if (((MemberExpression)expression.Body).Member.GetCustomAttribute(typeof(DefaultValueAttribute)) is DefaultValueAttribute attribute)
    {
        result = (TResult)attribute.Value;
        return true;
    }
    result = default;
    return false;
}

或者,如果未找到属性,则可以返回默认值,请使用以下命令:

public static TResult GetDefaultValue<TSource, TResult>(this TSource _, Expression<Func<TSource, TResult>> expression)
{
    if (((MemberExpression)expression.Body).Member.GetCustomAttribute(typeof(DefaultValueAttribute)) is DefaultValueAttribute attribute)
    {
        return (TResult)attribute.Value;
    }
    return default;
}

您还可以修改它以在找不到该属性时引发异常。

相关内容

  • 没有找到相关文章

最新更新