在D中返回类名的函数

时间:2011-06-22 18:46:15

标签: java d

比如说,类A1,A2,...,An都扩展了抽象类B. 我想A1,...,An有一个返回类名字符串的函数。 这在编译时肯定是已知的,但我想实现这个功能 B,并使用继承,以便所有Ai:s都能获得此功能。

在java中,通过让B拥有方法

,可以很容易地做到这一点
String getName() {
    return this.getClass();
}

或多或少。那么,我该怎么做D?此外,是否有一种方法,使用特征或类似方法来确定哪些类成员是公开的?

4 个答案:

答案 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");
}