我找到了这个解决方案:
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 code
的jgauffin代码我总是这样使用扩展程序:
foo.GetAttributeFrom<StringLengthAttribute>(nameof(Foo.Bar)).MaximumLength
有没有办法通过使用lambda来传递propertyName:
foo.GetAttributeFrom<StringLengthAttribute>(f => f.Bar).MaximumLength
提前谢谢!
答案 0 :(得分:3)
您可以将工作拆分为两个函数,以绕过为通用方法指定所有通用参数类型限制
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;
答案 1 :(得分:0)
方法可以是这样的:
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不是属性等。