读取方法的属性值

发布于 2024-08-26 06:41:45 字数 177 浏览 6 评论 0原文

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

[MyAttribute("Hello World")]
public void MyMethod()
{
    // Need to read the MyAttribute attribute and get its value
}

I need to be able to read the value of my attribute from within my Method, how can I do that?

[MyAttribute("Hello World")]
public void MyMethod()
{
    // Need to read the MyAttribute attribute and get its value
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夏了南城 2024-09-02 06:41:45

您需要调用 GetCustomAttributes 函数一个 MethodBase 对象。
获取 MethodBase 对象的最简单方法是调用 MethodBase.GetCurrentMethod。 (注意,你应该添加[MethodImpl(MethodImplOptions.NoInlined)]

例如:

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

You need to call the GetCustomAttributes function on a MethodBase object.
The simplest way to get the MethodBase object is to call MethodBase.GetCurrentMethod. (Note that you should add [MethodImpl(MethodImplOptions.NoInlining)])

For example:

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

You can also get the MethodBase manually, like this: (This will be faster)

MethodBase method = typeof(MyClass).GetMethod("MyMethod");
蝶…霜飞 2024-09-02 06:41:45
[MyAttribute("Hello World")]
public int MyMethod()
{
var myAttribute = GetType().GetMethod("MyMethod").GetCustomAttributes(true).OfType<MyAttribute>().FirstOrDefault();
}
[MyAttribute("Hello World")]
public int MyMethod()
{
var myAttribute = GetType().GetMethod("MyMethod").GetCustomAttributes(true).OfType<MyAttribute>().FirstOrDefault();
}
苏璃陌 2024-09-02 06:41:45

可用的答案大多已经过时。

这是当前的最佳实践:

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

The available answers are mostly outdated.

This is the current best practice:

class MyClass
{

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

This requires no casting and is pretty safe to use.

You can also use .GetCustomAttributes<T> to get all attributes of one type.

风渺 2024-09-02 06:41:45

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

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

If you store the default attribute value into a property (Name in my example) on construction, then you can use a static Attribute helper method:

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

Usage:

var name = Helper.GetMethodAttributeValue<MyAttribute, string>(MyMethod, x => x.Name);

My solution is based on that the default value is set upon the attribute construction, like this:

internal class MyAttribute : Attribute
{
    public string Name { get; set; }

    public MyAttribute(string name)
    {
        Name = name;
    }
}
失与倦" 2024-09-02 06:41:45

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

In case you are implementing the setup like @Mikael Engver mentioned above, and allow multiple usage. Here is what you can do to get the list of all the attribute values.

[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.
    }
}
驱逐舰岛风号 2024-09-02 06:41:45

我使用了这个方法:

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

I used this method :

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

Then can use like this:

var group = GetMethodAttributeValue<FieldAttribs, FieldGroups>(() => dd.Param2, a => a.Group);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文