简体   繁体   中英

Reflection says that interface method are virtual in the implemented type, when they aren't?

I have the following code in an unit test

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

which I call by

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

I want to ensure that all the methods from the interface are declared as virtual. The reason is because I'm applying a spring.net aspect and it will only apply to virtual methods.

The problem I'm having is that implMember.IsVirtual is always true, even when they are not declared as so in the declaring type.

What is wrong with my TestMethodsOf logic?

Cheers

All methods declared in an interface are marked as virtual abstract , and all methods that implement interface methods in classes are marked as virtual final , so the CLR knows it can't just call them directly - it has to do vtable lookups at runtime to call the right implementation. The interface implementations are still virtual, but you can't override them as they're final.

As an example, the following C# definition:

public interface IInterface {
    void Method();
}

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

compiles to the following 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() {}
}

我相信当您实现接口时,从该接口继承的方法会自动标记为虚拟,因此逻辑很好,并且不需要测试。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM