代码之家  ›  专栏  ›  技术社区  ›  mafu

如何使用反射访问显式实现的方法?

  •  5
  • mafu  · 技术社区  · 15 年前

    通常,我在反射中访问如下方法:

    class Foo
    {
        public void M () {
            var m = this.GetType ().GetMethod ("M");
            m.Invoke(this, new object[] {}); // notice the pun
        }
    }
    

    但是,当M是显式实现时,这将失败:

    class Foo : SomeBase
    {
        void SomeBase.M () {
            var m = this.GetType ().GetMethod ("M");
            m.Invoke(this, new object[] {}); // fails as m is null
        }
    }
    

    如何使用反射访问显式实现的方法?

    2 回复  |  直到 15 年前
        1
  •  12
  •   Fredrik Mörk    15 年前

    因为方法的名称不是 "M" "YourNamespace.SomeBase.M" . 因此,您需要指定该名称(以及适当的 BindingFlags ),或从接口类型获取方法。

    鉴于以下结构:

    namespace SampleApp
    {    
        interface IFoo
        {
            void M();
        }
    
        class Foo : IFoo
        {
            void IFoo.M()
            {
                Console.WriteLine("M");
            }
        }
    }
    

    …您可以这样做:

    Foo obj = new Foo();
    obj.GetType()
        .GetMethod("SampleApp.IFoo.M", BindingFlags.Instance | BindingFlags.NonPublic)
        .Invoke(obj, null);            
    

    …或者这个:

    Foo obj = new Foo();
    typeof(IFoo)
        .GetMethod("M")
        .Invoke(obj, null);  
    
        2
  •  3
  •   poizan42    7 年前

    InterfaceMapping 如果你想要一个 MethodInfo 为了实施。

    例如,如果我们有以下结构

    namespace LibBar
    {
      [AttributeUsage(AttributeTargets.Method)]
      public class AnswerAttribute : Attribute { }
    
      public interface IFoo
      {
        void Hello();
        int GetAnswer();
        object WhoAmI();
      }
    }
    

    在F项目中

    namespace LibFoo
    open LibBar
    
    type Foo() = 
        interface IFoo with
            [<Answer>]
            member this.GetAnswer() = 42
            member this.Hello() = printf "Hello, World!"
            member this.WhoAmI() = this :> obj
    

    GetAnswer() 通过思考,就可以得到 方法信息 对于接口

    Foo obj = new Foo();
    int answer = (int)typeof(IFoo)
      .GetMethod("GetAnswer")
      .Invoke(obj, null);
    

    但是,我们想看看实现是否具有AnswerAttribute。那么光有这个就不够了 方法信息 对于接口上的方法。方法的名称为 "LibBar.IFoo.GetAnswer"

    private static MethodInfo GetMethodImplementation(Type implementationType, MethodInfo ifaceMethod)
    {
      InterfaceMapping ifaceMap = implementationType.GetInterfaceMap(ifaceMethod.DeclaringType);
      for (int i = 0; i < ifaceMap.InterfaceMethods.Length; i++)
      {
        if (ifaceMap.InterfaceMethods[i].Equals(ifaceMethod))
          return ifaceMap.TargetMethods[i];
      }
      throw new Exception("Method missing from interface mapping??"); // We shouldn't get here
    }
    
    ...
    
      Foo obj = new Foo();
      MethodInfo ifaceMethod = typeof(IFoo).GetMethod("GetAnswer");
      MethodInfo implementationMethod = GetMethodImplementation(typeof(Foo), ifaceMethod);
      Console.WriteLine("GetAnswer(): {0}, has AnswerAttribute: {1}",
        implementationMethod.Invoke(obj, null),
        implementationMethod.GetCustomAttribute<AnswerAttribute>() != null);
    
    推荐文章