سؤال

ولدي واجهة أن تعرف بعض الطرق مع الصفات. وتحتاج هذه السمات يمكن الوصول إليها من طريقة الدعوة، ولكن الأسلوب لدي لا سحب سمات من واجهة. ما أنا في عداد المفقودين؟

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;
    }
}
هل كانت مفيدة؟

المحلول

ووmethodBase سيكون الأسلوب على الدرجة، وليس واجهة. وسوف تحتاج للبحث عن نفس الأسلوب على الواجهة. في C # هذا هو أبسط قليلا (نظرا لأنه يجب أن يكون مثل اسمه)، ولكن كنت في حاجة للنظر في الامور مثل تنفيذ صريح. إذا كان لديك كود VB سيكون اصعب، لأن طريقة VB "فو" يمكن تنفيذ أسلوب واجهة "بار". للقيام بذلك، وكنت بحاجة للتحقيق في مخطط واجهة:

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

نصائح أخرى

وسوف طريقة مارك تعمل من أجل واجهات غير عامة. ولكن يبدو أن أتعامل مع بعض الأدوية التي لها

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

ويبدو أن يتم استبدال T مع classType الفعلية في map.TargetMethods.

وبينما أنا أعترف أولا أنني قد حاولت أبدا إرفاق سمات واجهات ولكن سيكون شيئا مثل العمل التالية بالنسبة لك؟

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


  ....
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top