读取方法的属性值

我需要能够从我的方法中读取属性的值,我该怎么做呢?

[MyAttribute("Hello World")]
public void MyMethod()
{
// Need to read the MyAttribute attribute and get its value
}
55582 次浏览
[MyAttribute("Hello World")]
public int MyMethod()
{
var myAttribute = GetType().GetMethod("MyMethod").GetCustomAttributes(true).OfType<MyAttribute>().FirstOrDefault();
}

您需要在 MethodBase对象上调用 GetCustomAttributes函数。
获取 MethodBase对象的最简单方法是调用 MethodBase.GetCurrentMethod

例如:

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");

现有的答案大多已经过时了。

这是目前的最佳做法:

class MyClass
{


[MyAttribute("Hello World")]
public void MyMethod()
{
var method = typeof(MyClass).GetRuntimeMethod(nameof(MyClass.MyMethod), Array.Empty<Type>());
var attribute = method.GetCustomAttribute<MyAttribute>();
}
}

这不需要铸造,而且使用起来非常安全。

还可以使用 .GetCustomAttributes<T>获取一种类型的所有属性。

如果在构造时将默认属性值存储到属性(在我的示例中是 Name)中,那么可以使用静态 Attribute helper 方法:

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);