【问题标题】: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");
}

【问题讨论】:

    标签: c# .net reflection attributes default-value


    【解决方案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;
        }
        

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

        【讨论】:

          猜你喜欢
          • 2012-01-09
          • 2014-06-27
          • 1970-01-01
          • 2011-03-31
          • 1970-01-01
          • 2011-10-02
          • 2020-02-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多