1

There is a static method with which I get a property attribute of a specific type:

public static class TypeUtils
{
    public static TAttr GetAttribute<TAttr, TEntity>(
            Expression<Func<TEntity, object>> argumentFunc)
        where TAttr : Attribute
    {
        string propertyName = GetMemberInfo(argumentFunc).Member.Name;

        return typeof(TEntity)
            .GetProperty(propertyName,
                BindingFlags.Public | BindingFlags.Instance)
            ?.GetCustomAttributes(typeof(TAttr), false)
            .Cast<TAttr>().FirstOrDefault();
    }

    private static MemberExpression GetMemberInfo(Expression method)
    {
        if (method is not LambdaExpression lambda)
        {
            throw new ArgumentNullException(nameof(method));
        }

        MemberExpression memberExpr = null;

        if (lambda.Body.NodeType == ExpressionType.Convert)
        {
            memberExpr = ((UnaryExpression)lambda.Body)
                         .Operand as MemberExpression;
        }
        else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
        {
            memberExpr = lambda.Body as MemberExpression;
        }

        return memberExpr
               ?? throw new ArgumentException(null, nameof(method));
    }
}

// method is used like this
var attr = TypeUtils.GetAttribute<DisplayNameAttribute, Person>(p => p.Id);

Is it possible to change this method to a type extension method? I would to use it like this:

var attr = typeof(Person).GetAttribute<DisplayNameAttribute>(p => p.Id);

UPDATE

Most likely, I poorly formulated my question. I know what extension methods are and how they are created. The question here is how to create an extension method for a type based on an existing method, but not pass it the Person type as a second generic type. At the moment, everything that I was able to implement on my own is shown in the listing below. As you can see, we are essentially repeating ourselves, since when implementing an extension, the type is implicitly passed as a parameter to the method, but we explicitly specify it again. In this case, I do not see the advantages of this approach and it is better to use the existing solution then.
How to implement an extension so that you don't need to pass a type to it?

public static TAttr GetAttribute<TAttr, TEntity>(this Type type, Expression<Func<TEntity, object>> argumentFunc)
    where TAttr : Attribute
{
    MemberExpression memberExpression = getMemberInfo(argumentFunc);
    string propertyName = memberExpression.Member.Name;

    return type
        .GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance)
        ?.GetCustomAttributes(typeof(T), false)
        .Cast<T>().ToList();
}

// then can i use this extensions like so
typeof(Person).GetAttribute<DisplayNameAttribute, Person>(p => p.Id);
XelaNimed
  • 301
  • 5
  • 18
  • You just need this: `public static TAttr GetAttribute(this Type type, Expression> argumentFunc) where TAttr : Attribute { ... }`. – MakePeaceGreatAgain Mar 30 '21 at 13:58
  • You must pass it the property name `public static TAttr GetAttribute(this Type type, string propertyName) where TAttr : Attribute { return type .GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance) ?.GetCustomAttributes(typeof(TAttr), false) .Cast().FirstOrDefault(); }` You can still have it checked by the compiler by using `nameof`. Solutions using `dynamic`do not add safety. `var attr = typeof(Person).GetAttribute(nameof(IIdentifiable.Id)));` – Olivier Jacot-Descombes Mar 30 '21 at 14:11

0 Answers0