2008-10-30 18 views
18

Bazı yöntemlerin özniteliklerle tanımlandığı bir arabirim var. Bu özniteliklerin çağrı yönteminden erişilmesi gerekir, ancak sahip olduğum yöntem, öznitelikleri arabirimden çekmiyor. Neyi kaçırıyorum?Bir arabirimdeki özellikler

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

Yalnızca bir çeke, miras almanıza izin vermek için özniteliğinize uygun bayrağı ayarladınız değil mi? –

cevap

7

MethodBase, arabirim değil, sınıftaki yöntem olacaktır. Arayüzde aynı yöntemi aramanız gerekecek. C# içinde bu biraz daha basittir (çünkü adlandırılmış olması gerekir), ancak açık uygulama gibi şeyleri göz önünde bulundurmanız gerekir. Eğer VB kodunuz varsa daha zor olacaktır, çünkü VB metodu "Foo" bir arayüz metodu "Bar" uygulayabilir. Bunu yapmak için, arabirim harita araştırmak gerekir:

Ben ilk ben arabirimleri özelliklerini eklemek denedim hiç itiraf ancak olsa
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

Bu, Genel Arabirimler için çalışmıyor gibi görünüyor. IFoo Thad

+0

Bu – Thad

+0

'u işlemek için bir yol buldum. Az önce MSDN'de yaklaşık 1 günlük spelunking kaydettim. Teşekkür ederim. – dviljoen

0

olur sizin için aşağıdaki çalışmaları gibi bir şey?

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

Mark'ın yöntemi, jenerik olmayan arabirimler için çalışacaktır. Ama ben T map.TargetMethods fiili ClassType değiştirilir anlaşılmaktadır Generics'i

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

olması bazı uğraşıyorum anlaşılmaktadır.

+1

Bağlamın ne olduğu hakkında daha fazla bilgi verebilir misiniz? Ne yapmaya çalıştığını tam olarak hayal edemiyorum ... –