Я создал удобный метод, который использует дженерики для извлечения атрибута, применяемого к типу:
/// <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?
@thehennyy - На данный момент это не моя сильная сторона. Не могли бы вы помочь мне?
Вы имеете в виду такие как общие методы здесь: github.com/Microsoft/referencesource/blob/master/mscorlib/…? Они существуют уже некоторое время, и intellisense должен их втянуть.
О, я думаю, я понимаю, что вы имеете в виду ... что-то вроде ответа Хенни ниже. В любом случае оставлю свой другой комментарий. Обратите внимание: если вам нужны унаследованные атрибуты, его решение не будет работать со свойствами (или событиями), поскольку в этих случаях вам нужно вызывать Attribute.GetCustomAttributes.





Вы можете использовать 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);
}
}
Это должно быть выполнено с помощью выражений.