Reputation: 1089
I have found this solution:
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();
}
Code by jgauffin from How to retrieve Data Annotations from code
I always use the extension this way:
foo.GetAttributeFrom<StringLengthAttribute>(nameof(Foo.Bar)).MaximumLength
Is there a way to pass the propertyName by using a lambda like:
foo.GetAttributeFrom<StringLengthAttribute>(f => f.Bar).MaximumLength
Thank you in advance!
Upvotes: 2
Views: 1355
Reputation: 26989
The method can be like this:
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;
}
If you have a class like this with the attribute:
public class Rootobject
{
[StringLengthAttribute(10)]
public string Name { get; set; }
}
Then you will use it like this:
var obj = new Rootobject();
var max = obj.GetAttribute<StringLengthAttribute, Rootobject, string>((x) => x.Name)
.MaximumLength;
Improvements
Add error checking in case the attribute is not found or the lambda is not for a property etc.
Upvotes: 0
Reputation: 20754
You can split the work into two functions in order to bypass specifying all generic parameter type for a generic method restriction
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();
}
then use it like
foo.GetPropertyAttributes(f => f.Bar)
.GetFirst<StringLengthAttribute>()
.MaximumLength;
Upvotes: 3