返回 D 中类名的函数

发布于 2024-11-16 23:23:20 字数 285 浏览 1 评论 0原文

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

在java中,这可以很容易地完成,只要让B

String getName() {
    return this.getClass();
}

或多或少地拥有该方法即可。那么,我该如何在 D 中做到这一点呢?另外,有没有办法使用特征或类似的方法来确定哪些类成员是公共的?

Say, classes A1,A2,...,An all extends the abstract class B.
I would like A1,...,An to have a function that returns a string of the class name.
This is certainly known in compile-time, but I would like to implement this function in
B, and use inheritance so that all Ai:s get this functionality.

In java, this can easily be done, by letting B have the method

String getName() {
    return this.getClass();
}

more or less. So, how do I do this in D? Also, is there a way, using traits or similar, to determine which class members are public?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧时光的容颜 2024-11-23 23:23:20

只是 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

simply typeof(this).stringof

however this is fixed at compile time so inheritance doesn't change the value

this.typeinfo.name

will give the dynamic name of the classname of the instance

http://www.d-programming-language.org/expression.html#typeidexpression
http://www.d-programming-language.org/phobos/object.html#TypeInfo_Class

莫言歌 2024-11-23 23:23:20

它在编译时是已知的,但我认为在运行时评估类名需要进行分解。

这是运行时评估是否正常的情况:

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);
}

It is known at compile-time, but evaluating the class name at runtime requires demangling, I think.

Here it is if runtime-evaluation is okay:

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);
}
疏忽 2024-11-23 23:23:20

您只需使用 ClassName.stringof 即可获取类的名称

如果您希望它作为虚拟函数,那么我建议使用奇怪的重复模板模式

class B
{
    abstract string getName();
}

class BImpl(T)
{
    string getName() { return T.stringof; }
}

class A1 : BImpl!A1 { ... }
class A2 : BImpl!A2 { ... }
/+ etc. +/

不幸的是,目前无法确定哪些类成员是公开的。您可以使用 allMembers 特征 迭代所有成员。

foreach (member; __traits(allMembers, MyClass))
    writeln(member);

You can get the name of a class simply by using ClassName.stringof.

If you want it as a virtual function then I would recommend using the 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. +/

Unfortunately, at the moment there is no way to determine which class members are public. You can iterate all members by using the allMembers trait.

foreach (member; __traits(allMembers, MyClass))
    writeln(member);
澜川若宁 2024-11-23 23:23:20

这对我有用 - 假设运行时评估没问题,并且您只对实际的类 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");
}

Here is what works for me - assuming runtime-evaluation is okay, and you're only interested in the actual class name without the package-path or the module 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");
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文