首页 > 解决方案 > 从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;

上面的代码返回“Bar”而不是“Foo”,因为我们正在调用静态的名称,其中静态是我们从中调用 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());
        }
    }
}

但这会返回“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;

以上将输出: 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);
        }
    }
}

谢谢!

标签: c#.net

解决方案


在泛型的帮助下,您可以实现您正在寻找的东西。这是一个例子

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
{

}

推荐阅读