Reflection 从对象中找出它是谁的接口实例
我有以下场景(): 我使用接口,并为它们提供了不同的实现。现在我需要知道目前正在使用哪种具体的实现。所以在上面的例子中,我想从Reflection 从对象中找出它是谁的接口实例,reflection,d,Reflection,D,我有以下场景(): 我使用接口,并为它们提供了不同的实现。现在我需要知道目前正在使用哪种具体的实现。所以在上面的例子中,我想从c1知道它是类foo的一个实例 这在语言D中是可能的吗 我已经尝试过object(例如TypeInfo\u Class)和std.traits的可能性。不幸的是没有成功 当然,解决方法是为接口提供合适的元方法(): 然而,这对于D来说是非常麻烦和不寻常的。我可以很好地想象有一个更好的实现 致意 Thorsten实际上很简单:首先强制转换到对象,然后获取类型ID,然后执行n
c1
知道它是类foo
的一个实例
这在语言D中是可能的吗
我已经尝试过object
(例如TypeInfo\u Class
)和std.traits
的可能性。不幸的是没有成功
当然,解决方法是为接口提供合适的元方法():
然而,这对于D来说是非常麻烦和不寻常的。我可以很好地想象有一个更好的实现
致意
Thorsten实际上很简单:首先强制转换到
对象
,然后获取类型ID
,然后执行null
检查:
Object o = cast(Object) your_object;
if(o is null) { /* i don't think this ever happens but you should check anyway */ }
writeln(typeid(o)); // will tell the class name
如果您想在特定的类上调用一个方法,您可以直接强制转换到您的类,然后再次进行null检查
对象的中间转换允许typeid(又名classinfo)成功,而直接在接口上调用它总是返回接口本身的typeid。这是因为D接口被定义为非常薄,以最大限度地与其他语言兼容,并且不会自动假定运行时类型信息实际上通过它存在。但是cast-to对象告诉它您假设RTTI存在,然后typeid将提取它
请注意,typeid数据并没有提供大量的信息。。。它主要是语言运行库的动态转换、比较和其他功能所需要的。但是它有一个方便的方法是类名和toString方法,这就是writeln成功的原因。但是,如果您正在寻找更详细的运行时反射,则必须使用CT桥函数,或者更好,只需在接口中编写自己的方法
但是,如果您只需要类名,请使用该toString。它给出了完全限定的名称,包括模块名,因此您将得到类似于yourmodule.foo
的名称,而不是foo
。如果你愿意的话,你可以在圆点处切掉它
import std.stdio;
void main(string[] args)
{
inter1 c1 = new foo();
foo c2 = new foo();
writeln("Origin=interface: ", c1.strategyName);
writeln("Origin=class: ", c2.strategyName);
}
interface inter1 {
@property string strategyName() const;
}
class foo : inter1 {
@property string strategyName() const {
return "foo";
}
}
Object o = cast(Object) your_object;
if(o is null) { /* i don't think this ever happens but you should check anyway */ }
writeln(typeid(o)); // will tell the class name