我有一些接口类型的列表。对于调试,我想打印出列表中每个对象的基础类的名称:
import std.stdio, std.container;
interface IFace { }
class Foo : IFace { }
class Bar : IFace { }
unittest {
SList!IFace list;
list.insert(new Foo);
list.insert(new Bar);
foreach(obj ; list) writeln(obj.classinfo.name);
}
我希望
富
酒吧
但反而得到了
IFACE
IFACE
有没有办法在运行时从接口类型变量中提取实现类?
此外,如果IFace
是class
而不是interface
,我做会获得预期结果。为什么呢?
答案 0 :(得分:4)
将接口转换为Object
,然后获取typeid或classinfo:
foreach(obj ; list) writeln((cast(Object)obj).classinfo.name);
你 也应检查演员表上的null是否完全正确,也许做一个辅助函数来做到这一点,但如果你确定所有的接口都是来自Object,你会可以调试。
需要这样做的原因是D接口不一定代表D对象,因此类名实际上可能不可用。例如,它可能是在某些外部DLL中创建并通过接口访问的COM对象。它可能是D正在与之交谈的C ++类。或者更多,接口保持通用,因此它们可以作为通用....好吧,用各种语言和样式编写的各种组件之间的接口。
这也是为什么对Object的强制转换可能返回null:如果它是C ++类,它将无法转换回D Object
。
此外,如果IFace是一个类而不是一个接口,我确实得到了预期的结果。为什么呢?
一个类保证有一个D Object base,运行时类型信息可用,所以它只在那里工作。界面可以来自其他来源。