C# 读取方法属性的值

C# 读取方法属性的值,c#,.net,reflection,attributes,methods,C#,.net,Reflection,Attributes,Methods,我需要能够从我的方法中读取属性的值,我如何才能做到这一点 [MyAttribute("Hello World")] public void MyMethod() { // Need to read the MyAttribute attribute and get its value } 您需要在MethodBase对象上调用该函数。 获取MethodBase对象的最简单方法是调用。注意,您应该添加[MethodImplOptions.NoInLine] 例如: MethodBase

我需要能够从我的方法中读取属性的值,我如何才能做到这一点

[MyAttribute("Hello World")]
public void MyMethod()
{
    // Need to read the MyAttribute attribute and get its value
}
您需要在MethodBase对象上调用该函数。 获取MethodBase对象的最简单方法是调用。注意,您应该添加[MethodImplOptions.NoInLine]

例如:

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), new Type[]{});
    var attribute = method.GetCustomAttribute<MyAttribute>();
  }
}
这不需要铸造,使用起来非常安全


您还可以使用.GetCustomAttributes来获取一种类型的所有属性。

如果在我的构造示例中将默认属性值存储到属性名称中,则可以使用静态属性帮助器方法:

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

如果您正在实施上述@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.
    }
}

名字很好。几年过去了,快凌晨3点了,上面的评论绝对让我笑得流下了眼泪。。。太棒了@OdedHahahahah@Oded这太棒了,还有一些通用版本你不需要铸造!我认为在更新版本的.net中作为扩展实现的这些方法中,在4.0之后,访问者可以查看其他答案,而不是公认的答案
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;
    }
}
[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.
    }
}