Frage

Ich habe eine Schnittstelle, die einige Methoden mit Attributen definiert. Diese Attribute müssen von der rufenden Methode zugegriffen werden, aber die Methode, die ich habe nicht zieht die Attribute aus der Schnittstelle. Was bin ich?

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;
    }
}
War es hilfreich?

Lösung

Die Method wird die Methode für die Klasse, nicht die Schnittstelle. Sie werden nach der gleichen Methode auf der Schnittstelle zu suchen. In C # ist dies ein wenig einfacher (da es wie Namen muss sein), aber Sie würde Dinge wie explizite Implementierung berücksichtigen müssen. Wenn Sie VB-Code haben wird es schwieriger sein, da VB-Methode „Foo“ kann eine Interface-Methode „Bar“ implementieren. Dazu müssen Sie die Schnittstelle Karte untersuchen:

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

Andere Tipps

Mark-Methode für nicht-generische Schnittstellen arbeiten. Aber es scheint, dass ich mit einigen zu tun habe, die Generika haben

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

Es scheint, dass die T mit dem tatsächlichen Classtype in dem map.TargetMethods ersetzt wird.

Während ich zunächst gestehen, dass ich nie versucht, Attribute Schnittstellen zu befestigen, sondern würde so etwas wie die folgende Arbeit für Sie?

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


  ....
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top