反思说接口方法在实现类型中是虚拟的,当它们不是时?

Seb*_*Piu 12 c# reflection virtual spring.net

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

    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;
  }
Run Code Online (Sandbox Code Playgroud)

我打电话给他

Assert.IsTrue(TestMethodsOf<MyView, IMyView>());
Run Code Online (Sandbox Code Playgroud)

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

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

我的TestMethodsOf逻辑有什么问题?

干杯

the*_*oop 20

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

例如,以下C#定义:

public interface IInterface {
    void Method();
}

public class Class : IInterface {
    public void Method() {}
}
Run Code Online (Sandbox Code Playgroud)

编译成以下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() {}
}
Run Code Online (Sandbox Code Playgroud)