Pregunta

Tengo una interfaz que define algunos métodos con atributos. Es necesario acceder a estos atributos desde el método de llamada, pero el método que tengo no extrae los atributos de la interfaz. ¿Qué me estoy perdiendo?

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;
    }
}
¿Fue útil?

Solución

MethodBase será el método en la clase, no la interfaz. Deberá buscar el mismo método en la interfaz. En C # esto es un poco más simple (ya que debe tener el mismo nombre), pero debería considerar cosas como la implementación explícita. Si tiene un código VB, será más complicado, ya que el método VB " Foo " Puede implementar un método de interfaz " Bar " ;. Para hacer esto, necesitarías investigar el mapa de la interfaz:

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

Otros consejos

El método de Mark funcionará para interfaces no genéricas. Pero parece que estoy tratando con algunos que tienen genéricos

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

Parece que la T se reemplaza con el classType real en el mapa.TargetMethods.

Aunque primero confesaré que nunca he intentado adjuntar atributos a las interfaces, ¿funcionaría algo como lo siguiente para usted?

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


  ....
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top