比如说,类A1,A2,...,An都扩展了抽象类B. 我想A1,...,An有一个返回类名字符串的函数。 这在编译时肯定是已知的,但我想实现这个功能 B,并使用继承,以便所有Ai:s都能获得此功能。
在java中,通过让B拥有方法
,可以很容易地做到这一点String getName() {
return this.getClass();
}
或多或少。那么,我该怎么做D?此外,是否有一种方法,使用特征或类似方法来确定哪些类成员是公开的?
答案 0 :(得分:5)
只需typeof(this).stringof
但是这在编译时是固定的,因此继承不会改变值
this.typeinfo.name
将提供实例的类名的动态名称
http://www.d-programming-language.org/expression.html#typeidexpression
http://www.d-programming-language.org/phobos/object.html#TypeInfo_Class
答案 1 :(得分:3)
它在编译时已知,但在运行时评估类名需要解码,我想。
这是运行时评估是否合适:
import std.stdio;
import std.algorithm;
abstract class B {
string className() @property {
return this.classinfo.name.findSplit(".")[2];
}
}
class A1 : B { }
class A2 : B { }
void main()
{
auto a1 = new A1();
writeln(a1.className);
auto a2 = new A2();
writeln(a2.className);
}
答案 2 :(得分:3)
您只需使用ClassName.stringof
即可获得课程名称。
如果您想将其作为虚拟功能,我建议您使用Curiously Recurring Template Pattern:
class B
{
abstract string getName();
}
class BImpl(T)
{
string getName() { return T.stringof; }
}
class A1 : BImpl!A1 { ... }
class A2 : BImpl!A2 { ... }
/+ etc. +/
不幸的是,目前无法确定哪些班级成员是公开的。您可以使用allMembers trait迭代所有成员。
foreach (member; __traits(allMembers, MyClass))
writeln(member);
答案 3 :(得分:0)
这是对我有用的-假设运行时评估是可以的,并且您只对实际的 name 类感兴趣,而没有包路径或模块名。
#!/usr/bin/env rdmd
module test;
// test successful with DMD v2.063 (May 2013) through v2.086.0 (May 2019)
class A
{
public string derivedName() const
{
import std.string : lastIndexOf;
const startIndex = this.classinfo.name.lastIndexOf('.') + 1;
return this.classinfo.name[startIndex .. $];
}
}
class B : A
{
}
void main()
{
auto b = new B();
assert(b.derivedName == "B");
}