Domanda

Ho un'interfaccia che definisce alcuni metodi con attributi. È necessario accedere a questi attributi dal metodo di chiamata, ma il metodo che ho non estrae gli attributi dall'interfaccia. Cosa mi sto perdendo?

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;
    }
}
È stato utile?

Soluzione

methodBase sarà il metodo sulla classe, non l'interfaccia. Dovrai cercare lo stesso metodo sull'interfaccia. In C # questo è un po 'più semplice (dal momento che deve avere un nome simile), ma dovresti considerare cose come l'implementazione esplicita. Se hai un codice VB sarà più complicato, dal momento che il metodo VB "Foo" può implementare un metodo di interfaccia "Bar". Per fare ciò, dovresti esaminare la mappa dell'interfaccia:

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

Altri suggerimenti

Il metodo di Mark funzionerà per interfacce non generiche. Ma sembra che abbia a che fare con alcuni che hanno generici

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

Sembra che la T sia sostituita con il classType effettivo nella mappa.TargetMethods.

Mentre prima confesso che non ho mai provato ad associare attributi alle interfacce, ma qualcosa di simile al seguente funzionerebbe per te?

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


  ....
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top