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 asvirtual 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:
compiles to the following IL:
I believe when you implement an interface, the methods you inherit from the interface are automatically marked as virtual, so the logic's fine, and you don't need the test.