从一个对象中找出它是其实例的接口
Find out from an object as an interface whose instance it is
我有以下情况 (https://run.dlang.io/is/19OOW9):
import std.stdio;
void main(string[] args)
{
inter1 c1 = new foo();
foo c2 = new foo();
writeln("Origin=interface: ", typeof(c1).stringof);
writeln("Origin=class: ", typeof(c2).stringof);
}
interface inter1 {
}
class foo : inter1 {
}
我使用接口并为它们提供不同的实现。现在我需要知道当前正在使用哪个具体实现。所以在上面的例子中,我想从 c1
知道它是 class foo
.
的一个实例
这在 D 语言中可能吗?
我已经尝试了object
(例如TypeInfo_Class
)和std.traits
的可能性。可惜没有成功。
当然,解决方法是为接口提供合适的元方法 (https://run.dlang.io/is/Xnt0TO):
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";
}
}
然而,这对于 D 来说是麻烦且不寻常的。我可以想象有更好的实现方式。
此致
托斯滕
实际上很简单:首先转换为 Object
,然后获取 typeid
,在 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
如果你想调用特定 class 上的方法,你可以直接转换到你的 class,然后再次检查空值。
中间转换为 Object 允许 typeid(又名 classinfo)成功,而直接在接口上调用它总是 returns 接口本身的 typeid。这是因为 D 接口被定义为非常薄,以实现与其他语言的最大兼容性,并且不会自动假定 运行 时间类型信息实际上通过它存在。但是对 Object 的转换告诉它你假设 RTTI 存在,然后 typeid 将拉它。
请注意,typeid 数据不提供大量信息...它主要是动态转换、比较和语言 运行time 的其他功能所需要的。但是它有一个方便的方法是 class 名称和 toString 方法,这就是 writeln 成功的原因。但是,如果您正在寻找更详细的 运行 时间反射,则必须使用 CT 桥接功能来完成,或者可能更好,只需在界面中编写您自己的方法即可。
但如果您只需要 class 名称,请使用该 toString。它给出了完全限定的名称,包括模块名称,因此您将得到 yourmodule.foo
而不是 foo
。如果你喜欢,你可以通过在点处切片来切断它。
我有以下情况 (https://run.dlang.io/is/19OOW9):
import std.stdio;
void main(string[] args)
{
inter1 c1 = new foo();
foo c2 = new foo();
writeln("Origin=interface: ", typeof(c1).stringof);
writeln("Origin=class: ", typeof(c2).stringof);
}
interface inter1 {
}
class foo : inter1 {
}
我使用接口并为它们提供不同的实现。现在我需要知道当前正在使用哪个具体实现。所以在上面的例子中,我想从 c1
知道它是 class foo
.
这在 D 语言中可能吗?
我已经尝试了object
(例如TypeInfo_Class
)和std.traits
的可能性。可惜没有成功。
当然,解决方法是为接口提供合适的元方法 (https://run.dlang.io/is/Xnt0TO):
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";
}
}
然而,这对于 D 来说是麻烦且不寻常的。我可以想象有更好的实现方式。
此致
托斯滕
实际上很简单:首先转换为 Object
,然后获取 typeid
,在 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
如果你想调用特定 class 上的方法,你可以直接转换到你的 class,然后再次检查空值。
中间转换为 Object 允许 typeid(又名 classinfo)成功,而直接在接口上调用它总是 returns 接口本身的 typeid。这是因为 D 接口被定义为非常薄,以实现与其他语言的最大兼容性,并且不会自动假定 运行 时间类型信息实际上通过它存在。但是对 Object 的转换告诉它你假设 RTTI 存在,然后 typeid 将拉它。
请注意,typeid 数据不提供大量信息...它主要是动态转换、比较和语言 运行time 的其他功能所需要的。但是它有一个方便的方法是 class 名称和 toString 方法,这就是 writeln 成功的原因。但是,如果您正在寻找更详细的 运行 时间反射,则必须使用 CT 桥接功能来完成,或者可能更好,只需在界面中编写您自己的方法即可。
但如果您只需要 class 名称,请使用该 toString。它给出了完全限定的名称,包括模块名称,因此您将得到 yourmodule.foo
而不是 foo
。如果你喜欢,你可以通过在点处切片来切断它。