Общий метод для получения атрибута от члена типа - PullRequest
0 голосов
/ 02 октября 2018

Я создал удобный метод, который использует обобщенные значения для извлечения атрибута, примененного к типу:

/// <summary>
/// Return an attribute from the provided type if it exists on that type.
/// </summary>
/// <typeparam name="T">The type whose attribute <typeparamref name="TAttType"/> 
/// will be returned if it exists on that type.</typeparam>
/// <typeparam name="TAttType">The type of attribute that will be retrieved
/// on <typeparamref name="T"/> if it exists.</typeparam>
/// <returns>Return the attribute with type <typeparamref name="TAttType"/>, 
/// if it exists, from target type <typeparamref name="T"/> or else
/// return null.</returns>
public static TAttType GetAttribute<T, TAttType>() where TAttType:Attribute 
    => (TAttType) typeof(T).GetCustomAttribute(typeof(TAttType), false);

Хотя это работает только для атрибутов типов.Т.е. если у меня есть этот атрибут:

public class VehicleAttribute : Attribute
{
    public string Color { get; }
    public int NumWheels { get; }

    public VehicleAttribute(string color, int numWheels)
    {
        Color = color;
        NumWheels = numWheels;
    }
}

Я могу сделать это:

[Vehicle("Yellow", 6)]
public class Bus { }

И тогда это:

var att = ReflectionTools.GetAttribute<Bus, VehicleAttribute>();

Но если у меня есть свойство, подобноеэто (не то, чтобы это имело смысл, но только для демонстрационных целей):

[Vehicle("Blue", 5)]
public string Name { get; set; }

Я хочу использовать аналогичный подход.Есть ли способ, с помощью которого я могу использовать дженерики для облегчения поиска атрибута из любого System.Reflection.MemberInfo, а не только System.Type?

1 Ответ

0 голосов
/ 02 октября 2018

Вы можете использовать MemberExpression, чтобы указать члена, от которого вы хотите получить атрибут.Вот пример:

using System;
using System.Linq.Expressions;
using System.Reflection;

public class VehicleAttribute : Attribute
{
    public string Color { get; }
    public int NumWheels { get; }

    public VehicleAttribute(string color, int numWheels)
    {
        Color = color;
        NumWheels = numWheels;
    }
}

[Vehicle("Yellow", 6)]
public class Bus
{ 

    [Vehicle("Blue", 5)]
    public string Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(Test<Bus, VehicleAttribute>((x) => x.Name).Color);
    }

    static U Test<T, U>(Expression<Func<T, object>> expr) where U : Attribute
    {
        if(!(expr.Body is MemberExpression memberExpr))
        {
            throw new NotSupportedException("expr");
        }
        return (U)memberExpr.Member.GetCustomAttribute(typeof(U), false);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...