【问题标题】:Reflection says that interface method are virtual in the implemented type, when they aren't?反射说接口方法在实现类型中是虚拟的,当它们不是?
【发布时间】:2016-10-22 11:27:32
【问题描述】:

我在单元测试中有以下代码

    public bool TestMethodsOf<T, I>()
  {
   var impl = typeof(T);
   var valid = true;

   foreach (var iface in impl.GetInterfaces().Where(i => typeof(I).IsAssignableFrom(i)))
   {

    var members = iface.GetMethods();

    foreach (var member in members)
    {
     Trace.Write("Checking if method " + iface.Name + "." + member.Name + " is virtual...");
     var implMember = impl.GetMethod(member.Name, member.GetParameters().Select(c => c.ParameterType).ToArray());
     if (!implMember.IsVirtual)
     {
      Trace.WriteLine(string.Format("FAILED"));
      valid = false;
      continue;
     }

     Trace.WriteLine(string.Format("OK"));
    }
   }
   return valid;
  }

我称之为

Assert.IsTrue(TestMethodsOf<MyView, IMyView>());

我想确保接口中的所有方法都声明为虚拟方法。原因是我正在应用 spring.net 方面,它只适用于虚拟方法。

我遇到的问题是 implMember.IsVirtual 总是正确的,即使它们没有在声明类型中声明。

我的 TestMethodsOf 逻辑有什么问题?

干杯

【问题讨论】:

    标签: c# reflection virtual spring.net


    【解决方案1】:

    我相信当你实现一个接口时,你从接口继承的方法会自动标记为虚拟,所以逻辑没问题,你不需要测试。

    【讨论】:

    • 如果我试图重写声明类型中的方法,我做不到。在这种情况下,继承方面也没有覆盖我的方法调用,因此没有将它们检测为虚拟
    【解决方案2】:

    接口中声明的所有方法都标记为virtual abstract,类中实现接口方法的所有方法都标记为virtual final,所以CLR知道它不能直接调用它们——它必须做vtable在运行时查找以调用正确的实现。接口实现仍然是虚拟的,但您不能覆盖它们,因为它们是最终的。

    例如,以下C#定义:

    public interface IInterface {
        void Method();
    }
    
    public class Class : IInterface {
        public void Method() {}
    }
    

    编译为以下 IL:

    .class public interface abstract IInterface {
        .method public abstract virtual instance void Method() {}
    }
    
    .class public Class extends [mscorlib]System.Object implements IInterface {
        .method public specialname rtspecialname instance void .ctor() {}
        .method public virtual final instance void Method() {}
    }
    

    【讨论】:

    • 太棒了!所以我改变了我的代码来检查 IsFinal 而不是 IsVirtual 现在它工作正常。谢谢!
    猜你喜欢
    • 2021-11-02
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多