代码之家  ›  专栏  ›  技术社区  ›  Coppermill

读取方法的属性值

  •  54
  • Coppermill  · 技术社区  · 15 年前

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

    [MyAttribute("Hello World")]
    public void MyMethod()
    {
        // Need to read the MyAttribute attribute and get its value
    }
    
    5 回复  |  直到 6 年前
        1
  •  67
  •   SLaks    15 年前

    你需要打电话给 GetCustomAttributes 作用于 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 method = typeof(MyClass).GetMethod("MyMethod");
    
        2
  •  28
  •   EgorBo    15 年前
    [MyAttribute("Hello World")]
    public int MyMethod()
    {
    var myAttribute = GetType().GetMethod("MyMethod").GetCustomAttributes(true).OfType<MyAttribute>().FirstOrDefault();
    }
    
        3
  •  15
  •   Asken    7 年前

    现有的答案大多是过时的。

    这是当前的最佳实践:

    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> 获取一种类型的所有属性。

        4
  •  0
  •   Mikael Engver    8 年前

    如果将默认属性值存储到属性中( Name 在我的示例中)on construction,则可以使用静态属性帮助器方法:

    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;
        }
    }
    
        5
  •  0
  •   Hoang Minh    6 年前

    如果您正在实现上面提到的@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.
        }
    }