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