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

Posted

技术标签:

【中文标题】获取给定名称的属性的默认值【英文标题】:Get the default value of a property given its name 【发布时间】:2011-08-29 18:21:28 【问题描述】:

我有一个财产,(示例如下)。

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

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

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

是否可以让我的构造函数“发现”给定属性的默认值并进行相应设置?比如:

myctor()

   myVal = GetDefaultValueProperty<bool>("MyProperty");

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

您可以使用以下代码来获取您所追求的元数据。

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

【讨论】:

【参考方案3】:

这是基于 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;

如果未找到该属性,您也可以对其进行修改以引发异常。

【讨论】:

以上是关于获取给定名称的属性的默认值的主要内容,如果未能解决你的问题,请参考以下文章

如何获取所有 SQL Server 默认值和规则的名称

Groovy - 如何在不更新地图的情况下使用默认值获取地图值

访问对象中的属性与方法

在运行时从 Android 主题获取默认属性值?

组件的默认属性值

如果默认或给定值,则 ArgParse 参数错误无