2008-10-30 7 views
18

J'ai une interface qui définit certaines méthodes avec des attributs. Ces attributs doivent être accessibles à partir de la méthode appelante, mais la méthode que j'ai ne tire pas les attributs de l'interface. Qu'est-ce que je rate?Attributs sur une interface

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

Juste une vérification, vous avez placé le drapeau approprié sur votre attribut pour lui permettre d'être hérité n'est-ce pas? –

Répondre

7

La méthode method sera la méthode de la classe, pas l'interface. Vous devrez rechercher la même méthode sur l'interface. En C# c'est un peu plus simple (car il doit être similaire), mais vous devez considérer des choses comme l'implémentation explicite. Si vous avez du code VB, ce sera plus compliqué, puisque la méthode VB "Foo" peut implémenter une méthode d'interface "Bar". Pour ce faire, vous devrez enquêter sur 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; 
    } 
} 
+0

Cela ne semble pas fonctionner pour les interfaces génériques. IFoo Thad

+0

J'ai trouvé un moyen de gérer cela – Thad

+0

Vous venez de me sauver environ 1/2 journée spelunking sur MSDN. Je vous remercie. – dviljoen

0

Alors que je vais d'abord avouer que je ne l'ai jamais essayé d'attacher des attributs aux interfaces mais serait quelque chose comme les travaux suivants 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; 
    } 


    .... 
} 
2

La méthode de Mark fonctionnera pour les interfaces non génériques. Mais il semble que je traite avec certains génériques qui ont

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

Il semble que le T est remplacé par le ClassType réelle dans les map.TargetMethods.

+1

Pouvez-vous donner plus d'informations sur le contexte? Je ne peux pas visualiser ce que vous essayez de faire ... –

Questions connexes