Атрибуты на интерфейсе - PullRequest
       30

Атрибуты на интерфейсе

18 голосов
/ 31 октября 2008

У меня есть интерфейс, который определяет некоторые методы с атрибутами. Эти атрибуты должны быть доступны из вызывающего метода, но метод, который я имею, не извлекает атрибуты из интерфейса. Чего мне не хватает?

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

Ответы [ 3 ]

7 голосов
/ 31 октября 2008

methodBase будет методом класса, а не интерфейса. Вам нужно будет найти тот же метод в интерфейсе. В C # это немного проще (так как оно должно быть одноименным), но вам нужно учитывать такие вещи, как явная реализация. Если у вас есть VB-код, это будет сложнее, так как VB-метод "Foo" может реализовать интерфейсный метод "Bar". Для этого вам нужно изучить карту интерфейса:

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;
    }
}
2 голосов
/ 31 октября 2008

Метод Марка будет работать для неуниверсальных интерфейсов. Но похоже, что я имею дело с некоторыми, у которых есть дженерики

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

Похоже, что T заменяется фактическим classType на карте. Методы цели.

0 голосов
/ 31 октября 2008

Хотя я сначала признаюсь, что я никогда не пытался прикрепить атрибуты к интерфейсам, но что-то вроде следующей работы для вас?

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


  ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...