web-dev-qa-db-fra.com

Lire la valeur d'un attribut d'une méthode

Je dois pouvoir lire la valeur de mon attribut depuis ma méthode, comment puis-je faire cela?

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

Vous devez appeler la fonction GetCustomAttributes sur un objet MethodBase.
Le moyen le plus simple d’obtenir l’objet MethodBase consiste à appeler MethodBase.GetCurrentMethod . (Notez que vous devriez ajouter [MethodImpl(MethodImplOptions.NoInlining)])

Par exemple:

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

Vous pouvez également obtenir manuellement la MethodBase, comme ceci: (Ce sera plus rapide)

MethodBase method = typeof(MyClass).GetMethod("MyMethod");
66
SLaks
[MyAttribute("Hello World")]
public int MyMethod()
{
var myAttribute = GetType().GetMethod("MyMethod").GetCustomAttributes(true).OfType<MyAttribute>().FirstOrDefault();
}
28
Nagg

Les réponses disponibles sont pour la plupart obsolètes. 

C'est la meilleure pratique actuelle:

class MyClass
{

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

Cela ne nécessite aucun casting et est assez sûr à utiliser.

Vous pouvez également utiliser .GetCustomAttributes<T> pour obtenir tous les attributs d'un type.

15
Mafii

Si vous stockez la valeur d'attribut par défaut dans une propriété (Name dans mon exemple) lors de la construction, vous pouvez utiliser une méthode d'assistance Attribute statique:

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

Ma solution est basée sur le fait que la valeur par défaut est définie sur la construction d'attribut, comme ceci:

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

    public MyAttribute(string name)
    {
        Name = name;
    }
}
0
Mikael Engver

Au cas où vous implémenteriez la configuration telle que @Mikael Engver mentionnée ci-dessus, autorisez plusieurs utilisations. Voici ce que vous pouvez faire pour obtenir la liste de toutes les valeurs d'attribut.

[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.
    }
}
0
Hoang Minh