反射说接口方法在实现的类型中是虚拟的,但它们不是吗?
我在单元测试中有以下代码
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 始终为 true,即使它们没有在声明类型中如此声明。
我的 TestMethodsOf 逻辑有什么问题?
干杯
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
所有在接口中声明的方法都被标记为
virtualabstract
,所有在类中实现接口方法的方法都被标记为virtualfinal
,因此CLR知道它不能只是直接调用它们 - 它必须在运行时进行 vtable 查找才能调用正确的实现。接口实现仍然是虚拟的,但您不能覆盖它们,因为它们是最终的。例如,以下 C# 定义:
编译为以下 IL:
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.