从 C# 中的抽象类获取调用类名

pan*_*sru 4 .net c#

我最近开始学习 C#,我正在使用各种语言进行编程,如 PHP、JavaScript、Go、Rust、Elixir、一点 Java 和 Python。

我一直对 C# 着迷,现在我决定尝试一下。

到目前为止一切顺利,我学习一门新语言的过程是尝试复制其他语言的各种东西,尤其是我最擅长的 PHP。

TLTR: 我如何在 C# 中实现这个?

<?php
declare(strict_types=1);

abstract class Foo
{
    public static function className(): string
    {
        return static::class;
    }
}

final class Bar extends Foo
{
}

echo Bar::className() . PHP_EOL;
Run Code Online (Sandbox Code Playgroud)

上面的代码返回“Bar”而不是“Foo”,因为我们正在调用 static 的名称,其中 static 是我们从中调用 className 方法的类。

在 C# 中我设法做到了这一点:

using System;
using System.Reflection;

namespace LearningConsole
{
    abstract class Foo
    {
        public static string ClassName()
        {
            return MethodBase.GetCurrentMethod().DeclaringType.Name;
        }
    }

    class Bar : Foo
    {

    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Bar.ClassName());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但这返回“Foo”类名而不是“Bar”,有没有办法获取调用 ClassName 方法的类的名称?

先感谢您!

编辑: 我使用静态方法的原因是我试图在 C# 中完成类似的事情,就像在 PHP 中一样:

<?php
declare(strict_types=1);

interface Dummy {}

abstract class Base implements Dummy
{
    public static function create(...$args): Dummy
    {
        $callingClass = static::class;
        return new $callingClass(...$args);
    }
}

final class Bar extends Base
{
    protected function __construct() {}
}

final class Foo extends Base
{
    protected function __construct() {}
}

$foo = Foo::create();
$bar = Bar::create();
echo get_class($foo) . PHP_EOL.
     get_class($bar) . PHP_EOL;
Run Code Online (Sandbox Code Playgroud)

上面将输出:Foo Bar

也许在 C# 中,这种“魔法”被认为是不好的做法,但它在各种场合都可能很方便。

谢谢!

编辑 2: C# 不起作用(显然),但我的理解是,以某种方式实现上述示例可能是一个很好的折衷方案:

using System;
using System.Reflection;

namespace LearningConsole
{
    interface Dummy
    {
    }

    abstract class Base : Dummy
    {
        public static Dummy Create(Dummy obj, params dynamic[] args)
        {
            var constructor = typeof(obj).GetConstructor();
            constructor.invoke(null, args);
        }
    }

    class Foo : Base
    {
    }

    class Bar : Base
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
            var foo = Base.Create(Foo, null);
            var bar = Base.Create(Bar, null);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

bhm*_*ler 7

通过泛型的一点帮助,您可以实现您正在寻找的目标。这是一个例子

class Program
{
    static void Main(string[] args)
    {
        var foo = Base.Create<Foo>();
        var bar = Base.Create<Bar>();
        Console.WriteLine(foo.GetType().Name);
        Console.WriteLine(bar.GetType().Name);
        Console.ReadKey();
    }
}

public abstract class Base
{
    public static T Create<T>(params object[] args) where T : Base
    {
        return (T)Activator.CreateInstance(typeof(T), args);
    }
}

public class Bar : Base
{

}

public class Foo : Base
{

}
Run Code Online (Sandbox Code Playgroud)