2

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!

2 Answers 2

3

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;
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.