首页 > 解决方案 > 如何调试单声道运行时调用看似随机的getter而不是接口方法

问题描述

我有一个由单声道运行时调用看似随机的 getter 而不是接口方法引起的问题。

我把它的核心缩小到:

IGraphElementEditorData test = provider.CreateEditorData();

if (!typeof(IGraphElementEditorData).IsAssignableFrom(test))
{
    Debug.LogWarning("Please don't get logged.");
}

不幸的是,它被记录了:

日志

显然,运行时在这里做错了,破坏了类型安全。

该程序在 Unity 的 Mono 2.X 运行时上运行。

进一步调查,我发现provider.CreateEditorData()实际上在提供程序本身上调用了一个完全不同的方法:它调用了 的 getter provider.source,它甚至不兼容类型:

0x0000000031E8E84B (Mono JIT Code) Bolt.InvalidConnection:get_source ()
0x000000003493D53F (Mono JIT Code) Bolt.UnitConnection`2<object, object>:Ludiq.IConnection<Bolt.IUnitOutputPort,Bolt.IUnitInputPort>.get_source ()
0x00000000321F719A (Mono JIT Code) Ludiq.GraphPointer:GetElementEditorData<object> (Ludiq.IGraphElementEditorDataProvider)

提供者类型位于涉及接口、抽象类和泛型的复杂继承链中,此时我什至不知道如何开始隔离问题。

我在问我该如何调试这个?这是我第一次遇到这样的问题,而且我对 Mono 运行时术语还不够熟悉,甚至无法开始搜索。据我了解,这似乎是方法指针的虚拟表(vtable)的问题,但我找不到与我的问题匹配的 Mono 跟踪软件的错误报告。

标签: c#unity3dinterfacemonovtable

解决方案


IsAssignableFrom 接受一个Type参数。您传入的对象是一个类型 IGraphElementEditorData的对象,它不是a Type(并且不能是1),这应该会引发编译器错误“无法从 IGraphElementEditorData 转换为 Type”

您可能正在寻找的是:

IGraphElementEditorData test = provider.CreateEditorData();

if (!typeof(IGraphElementEditorData).IsAssignableFrom(test.GetType()))
{
    Debug.LogWarning("Please don't get logged.");
}

无论如何,当我运行此代码时,我没有收到日志消息。

1接口不能扩展类。


推荐阅读