Question

J'ai une interface qui définit certaines méthodes avec des attributs. Il faut accéder à ces attributs à partir de la méthode d’appel, mais la méthode que j’ai ne tire pas les attributs de l’interface. Qu'est-ce qui me manque?

public class SomeClass: ISomeInterface
{
    MyAttribute GetAttribute()
    {
        StackTrace stackTrace = new StackTrace();
        StackFrame stackFrame = stackTrace.GetFrame(1);
        MethodBase methodBase = stackFrame.GetMethod();
        object[] attributes = methodBase.GetCustomAttributes(typeof(MyAttribute), true);
        if (attributes.Count() == 0)
            throw new Exception("could not find MyAttribute defined for " + methodBase.Name);
        return attributes[0] as MyAttribute;
    }

    void DoSomething()
    {
        MyAttribute ma = GetAttribute();
        string s = ma.SomeProperty;
    }
}
Était-ce utile?

La solution

La méthode sera la méthode de la classe, pas l'interface. Vous devrez rechercher la même méthode sur l'interface. En C #, ceci est un peu plus simple (puisqu'il doit porter le même nom), mais vous devrez envisager des choses comme une implémentation explicite. Si vous avez du code VB, ce sera plus compliqué, car la méthode VB " Foo " peut implémenter une méthode d'interface "Bar". Pour ce faire, vous devez examiner la carte d'interface:

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
interface IFoo
{
    void AAA(); // just to push Bar to index 1
    [Description("abc")]
    void Bar();
}
class Foo : IFoo
{
    public void AAA() { } // just to satisfy interface
    static void Main()
    {
        IFoo foo = new Foo();
        foo.Bar();
    }
    void IFoo.Bar()
    {
        GetAttribute();
    }

    void GetAttribute()
    { // simplified just to obtain the [Description]

        StackTrace stackTrace = new StackTrace();
        StackFrame stackFrame = stackTrace.GetFrame(1);
        MethodBase classMethod = stackFrame.GetMethod();
        InterfaceMapping map = GetType().GetInterfaceMap(typeof(IFoo));
        int index = Array.IndexOf(map.TargetMethods, classMethod);
        MethodBase iMethod = map.InterfaceMethods[index];
        string desc = ((DescriptionAttribute)Attribute.GetCustomAttribute(iMethod, typeof(DescriptionAttribute))).Description;
    }
}

Autres conseils

La méthode de Mark fonctionnera pour les interfaces non génériques. Mais il semble que j’ai affaire à des génériques

interface IFoo<T> {}
class Foo<T>: IFoo<T>
{
  T Bar()
}

Il semble que le T soit remplacé par le classType réel dans la map.TargetMethods.

Bien que je reconnaisse d’abord que je n’ai jamais essayé d’attacher des attributs à des interfaces, quelque chose comme ce qui suit fonctionne pour vous?

public abstract class SomeBaseClass: ISomeInterface
{
     [MyAttribute]
     abstract void MyTestMethod();


}

public SomeClass : SomeBaseClass{

  MyAttribute GetAttribute(){
      Type t = GetType();
      object[] attibutes = t.GetCustomAttributes(typeof(MyAttribute), false);

      if (attributes.Count() == 0)
            throw new Exception("could not find MyAttribute defined for " + methodBase.Name);
        return attributes[0] as MyAttribute;
  }


  ....
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top