2008-10-30 15 views
18

Ich habe eine Schnittstelle, die einige Methoden mit Attributen definiert. Auf diese Attribute muss von der aufrufenden Methode zugegriffen werden, aber die Methode, die ich habe, zieht die Attribute nicht aus der Schnittstelle. Was vermisse ich?Attribute auf einer Schnittstelle

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

Nur ein Häkchen, Sie haben das entsprechende Flag auf Ihrem Attribut gesetzt, damit es vererbt werden kann, nicht wahr? –

Antwort

7

Die methodBase ist die Methode für die Klasse, nicht die Schnittstelle. Sie müssen nach der gleichen Methode auf der Schnittstelle suchen. In C# ist das ein wenig einfacher (da es ähnlich benannt sein muss), aber Sie müssten Dinge wie explizite Implementierung in Betracht ziehen. Wenn Sie VB-Code haben, wird es schwieriger, da die VB-Methode "Foo" eine Interface-Methode "Bar" implementieren kann. Um dies zu tun, müssen Sie die Interface 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; 
    } 
} 
+0

Dies scheint nicht für generische Schnittstellen zu funktionieren. IFoo Thad

+0

Ich habe einen Weg gefunden, damit umzugehen – Thad

+0

Sie haben mich nur etwa 1/2 Tag Spelunking auf MSDN gespeichert. Vielen Dank. – dviljoen

0

Während ich zunächst gestehen, dass ich nie Attribute Schnittstellen zu befestigen versucht, aber 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; 
    } 


    .... 
} 
2

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

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

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

+1

Können Sie mehr Informationen über den Kontext geben? Ich kann mir nicht genau vorstellen, was du zu tun versuchst ... –

Verwandte Themen