C# 接口上的属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/251806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Attributes on an interface
提问by Thad
I have a interface that defines some methods with attributes. These attributes need to be accessed from the calling method, but the method I have does not pull the attributes from the interface. What am I missing?
我有一个接口,它定义了一些带有属性的方法。这些属性需要从调用方法中访问,但是我的方法并没有从接口中拉取这些属性。我错过了什么?
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;
}
}
采纳答案by Marc Gravell
The methodBase will be the method on the class, not the interface. You will need to look for the same method on the interface. In C# this is a little simpler (since it must be like-named), but you would need to consider things like explicit implementation. If you have VB code it will be trickier, since VB method "Foo" can implement an interface method "Bar". To do this, you would need to investigate the interface map:
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;
}
}
回答by sbeskur
While I will first confess that I have never tried to attach attributes to Interfaces but would something like the following work for you?
虽然我首先要承认我从未尝试过将属性附加到接口,但以下内容对您有用吗?
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;
}
....
}
回答by Thad
Mark's method will work for non-generic interfaces. But it appears that I am dealing with some that have generics
Mark 的方法适用于非通用接口。但似乎我正在处理一些具有泛型的
interface IFoo<T> {}
class Foo<T>: IFoo<T>
{
T Bar()
}
It appears that the T is replaced with the actual classType in the map.TargetMethods.
看起来 T 被 map.TargetMethods 中的实际 classType 替换了。