Прочитайте значение атрибута метода
Мне нужно иметь возможность прочитать значение моего атрибута из моего метода, как я могу это сделать?
[MyAttribute("Hello World")]
public void MyMethod()
{
// Need to read the MyAttribute attribute and get its value
}
6 ответов
Вам нужно позвонить GetCustomAttributes
функция на MethodBase
объект.
Самый простой способ получить MethodBase
объект призвать MethodBase.GetCurrentMethod
, (Обратите внимание, что вы должны добавить [MethodImpl(MethodImplOptions.NoInlining)]
)
Например:
MethodBase method = MethodBase.GetCurrentMethod();
MyAttribute attr = (MyAttribute)method.GetCustomAttributes(typeof(MyAttribute), true)[0] ;
string value = attr.Value; //Assumes that MyAttribute has a property called Value
Вы также можете получить MethodBase
вручную, вот так: (это будет быстрее)
MethodBase method = typeof(MyClass).GetMethod("MyMethod");
[MyAttribute("Hello World")]
public int MyMethod()
{
var myAttribute = GetType().GetMethod("MyMethod").GetCustomAttributes(true).OfType<MyAttribute>().FirstOrDefault();
}
Доступные ответы в основном устарели.
Это текущая лучшая практика:
class MyClass
{
[MyAttribute("Hello World")]
public void MyMethod()
{
var method = typeof(MyClass).GetRuntimeMethod(nameof(MyClass.MyMethod), new Type[]{});
var attribute = method.GetCustomAttribute<MyAttribute>();
}
}
Это не требует кастинга и довольно безопасно для использования.
Вы также можете использовать .GetCustomAttributes<T>
чтобы получить все атрибуты одного типа.
Если вы сохраните значение атрибута по умолчанию в свойстве (Name
в моем примере) на конструкции, то вы можете использовать статический вспомогательный метод Attribute:
using System;
using System.Linq;
public class Helper
{
public static TValue GetMethodAttributeValue<TAttribute, TValue>(Action action, Func<TAttribute, TValue> valueSelector) where TAttribute : Attribute
{
var methodInfo = action.Method;
var attr = methodInfo.GetCustomAttributes(typeof(TAttribute), true).FirstOrDefault() as TAttribute;
return attr != null ? valueSelector(attr) : default(TValue);
}
}
Использование:
var name = Helper.GetMethodAttributeValue<MyAttribute, string>(MyMethod, x => x.Name);
Мое решение основано на том, что значение по умолчанию устанавливается на конструкцию атрибута, например так:
internal class MyAttribute : Attribute
{
public string Name { get; set; }
public MyAttribute(string name)
{
Name = name;
}
}
В случае, если вы реализуете настройку, такую как @Mikael Engver, упомянутую выше, и допускаете многократное использование. Вот что вы можете сделать, чтобы получить список всех значений атрибутов.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class TestCase : Attribute
{
public TestCase(string value)
{
Id = value;
}
public string Id { get; }
}
public static IEnumerable<string> AutomatedTests()
{
var assembly = typeof(Reports).GetTypeInfo().Assembly;
var methodInfos = assembly.GetTypes().SelectMany(m => m.GetMethods())
.Where(x => x.GetCustomAttributes(typeof(TestCase), false).Length > 0);
foreach (var methodInfo in methodInfos)
{
var ids = methodInfo.GetCustomAttributes<TestCase>().Select(x => x.Id);
yield return $"{string.Join(", ", ids)} - {methodInfo.Name}"; // handle cases when one test is mapped to multiple test cases.
}
}
Я использовал этот метод:
public static TAttributeMember? GetMethodAttributeValue<TAttribute, TAttributeMember>(Expression<Func<object>> property, Func<TAttribute, TAttributeMember> valueSelector) where TAttribute : Attribute
{
var methodInfo = ((MemberExpression)property.Body).Member as PropertyInfo;
var attr = methodInfo?.GetCustomAttributes(typeof(TAttribute), true).FirstOrDefault() as TAttribute;
return attr != null && valueSelector != null ? valueSelector(attr) : default(TAttributeMember);
}
Затем можно использовать так:
var group = GetMethodAttributeValue<FieldAttribs, FieldGroups>(() => dd.Param2, a => a.Group);