【问题标题】:Attributes on an interface接口的属性
【发布时间】:2010-09-20 02:10:18
【问题描述】:

我有一个接口,它定义了一些带有属性的方法。这些属性需要从调用方法中访问,但是我有的方法并没有从接口中拉取属性。我错过了什么?

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

【问题讨论】:

  • 只是检查一下,您已经在属性上设置了适当的标志以允许它被继承,不是吗?

标签: c# reflection attributes interface


【解决方案1】:

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

【讨论】:

  • 您刚刚为我节省了大约 1/2 天的 MSDN 探索时间。谢谢。
【解决方案2】:

Mark 的方法适用于非泛型接口。但似乎我正在处理一些具有泛型的问题

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

看来 T 被 map.TargetMethods 中的实际 classType 替换了。

【讨论】:

  • 你能提供更多关于上下文的信息吗?我无法完全想象你想要做什么......
【解决方案3】:

虽然我首先要承认我从未尝试将属性附加到接口,但您是否希望以下类似的方法对您有用?

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


  ....
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    相关资源
    最近更新 更多