【问题标题】:Pass property name by lambda expression for reading attribute values通过 lambda 表达式传递属性名称以读取属性值
【发布时间】:2017-03-18 13:33:43
【问题描述】:

我找到了这个解决方案:

public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute
{
    var attrType = typeof(T);
    var property = instance.GetType().GetProperty(propertyName);
    return (T)property .GetCustomAttributes(attrType, false).First();
}

How to retrieve Data Annotations from codejgauffin 的代码

我总是这样使用扩展:

foo.GetAttributeFrom<StringLengthAttribute>(nameof(Foo.Bar)).MaximumLength

有没有办法通过使用像这样的 lambda 来传递 propertyName:

foo.GetAttributeFrom<StringLengthAttribute>(f => f.Bar).MaximumLength

提前谢谢你!

【问题讨论】:

    标签: c# .net reflection lambda


    【解决方案1】:

    您可以将工作拆分为两个函数,以绕过为泛型方法指定所有泛型参数类型限制

    public static object[] GetPropertyAttributes<TObject, TProperty>(
        this TObject instance,
        Expression<Func<TObject, TProperty>> propertySelector)
    {
        //consider handling exceptions and corner cases
        var propertyName = ((PropertyInfo)((MemberExpression)propertySelector.Body).Member).Name;
        var property = instance.GetType().GetProperty(propertyName);
        return property.GetCustomAttributes(false);
    }
    
    public static T GetFirst<T>(this object[] input) where T : Attribute
    {
        //consider handling exceptions and corner cases
        return input.OfType<T>().First();
    }
    

    然后像这样使用它

    foo.GetPropertyAttributes(f => f.Bar)
       .GetFirst<StringLengthAttribute>()
       .MaximumLength;
    

    【讨论】:

      【解决方案2】:

      方法可以是这样的:

      public static TAtt GetAttribute<TAtt,TObj,TProperty>(this Rootobject inst, 
          Expression<Func<TObj,TProperty>> propertyExpression)
               where TAtt : Attribute
            {
               var body = propertyExpression.Body as MemberExpression;
               var expression = body.Member as PropertyInfo;
               var ret = (TAtt)expression.GetCustomAttributes(typeof(TAtt), false).First();
      
               return ret;
            }
      

      如果你有一个这样的类具有属性:

      public class Rootobject
      {
        [StringLengthAttribute(10)]
        public string Name { get; set; }
      }
      

      然后你会这样使用它:

      var obj = new Rootobject();
               var max = obj.GetAttribute<StringLengthAttribute, Rootobject, string>((x) => x.Name)
                            .MaximumLength;
      

      改进

      添加错误检查,以防找不到属性或 lambda 不适用于属性等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-14
        相关资源
        最近更新 更多