【问题标题】:How to get the class name of a derived class when executing a static method in the base class?在基类中执行静态方法时如何获取派生类的类名?
【发布时间】:2010-02-19 10:23:18
【问题描述】:

下面我想调用 MyOtherClass.MyStaticMethod() 来输出“MyOtherClass”,这可能吗?我目前所有的尝试都给了我“MyClass”。

我遇到的问题是我不能轻易更改 MyOtherClass,因为有 100 个类从 MyClass 扩展而来。

public class MyClass
{
    public static string MyStaticMethod()
    {
        string className = typeof(MyClass).Name;
        Console.WriteLine(className);
    }
}
public class MyOtherClass : MyClass{ }

【问题讨论】:

标签: c# .net


【解决方案1】:

你不需要它是一个实例方法,然后调用

string className = typeof(this).Name;

【讨论】:

  • 它必须是静态的,因为创建 MyOtherClass 的实例只是为了调用 MyStatic 方法是不可行的
  • 这就是为什么我说让它成为一个实例方法!
【解决方案2】:

在 C# 和 Java 中,您可以重载静态方法,但不能覆盖它。也就是说,不存在静态方法的多态性和继承性。 (详情请见this question

静态方法中没有this 的概念,因此无法以多态方式获取类型。这意味着您需要为每个类定义一个静态方法以打印正确的类型。

【讨论】:

    【解决方案3】:

    这与我上周刚问的一个问题有点相关:C# static member “inheritance” - why does this exist at all?

    切入正题,C# 并不真正支持静态方法继承 - 所以,你不能按照你的要求去做。不幸的是,可以写 MyOtherClass.MyStaticMethod() - 但这并不意味着有任何真正的继承发生:在幕后,这只是范围规则非常宽松。

    编辑:虽然你不能直接这样做,但你可以做 C++ 程序员所说的 Curiously Recurring Template Pattern 并与泛型非常接近[1]

    public class MyClass<TDerived> where TDerived:MyClass<TDerived> {
        public static string MyStaticMethod() { return  typeof(TDerived).Name; }
    }
    public class MyOtherClass : MyClass<MyOtherClass> { }
    public class HmmClass:MyOtherClass { }
    
    void Main() {
        MyOtherClass.MyStaticMethod().Dump(); //linqpad says MyOtherClass
        HmmClass.MyStaticMethod().Dump();  //linqpad also says MyOtherClass
    }
    

    在这里,您确实需要更新子类 - 但只是以较小的方式。

    【讨论】:

    • 但是,这是一个重大的代码更改,因为 OP 指定“有 100 个从 MyClass 扩展的类”。
    • 是的,但它比我能想到的任何其他替代方案都简单 - 编译器可以在这里为您提供帮助,因为添加泛型类型参数将意味着对 MyClass 的任何非泛型引用都将无效.我以前做过这种重构(可能超过 1000 次引用)——下一个错误、去修复等令人麻木的 F8,但最糟糕的是,这只是一天的工作。
    • 在这种情况下,正则表达式实际上可能会自动修复所有编译错误;只需在 VS.NET 的古怪语法(或类似的搜索)中将 ^{.*class {.*}.* : .* }MyClass{.*}$ 替换为 \1MyClass&lt;\2&gt;\3
    【解决方案4】:

    从 .NET 框架 3.5 版开始,您可以使用扩展函数来检索有关类实例的信息。

    public static class MyClassExtensions {
      public static string Name(this MyClass instance) {
        return typeof(instance).Name;
      }
    }
    

    提供实例方法,无需修改 MyOtherClass 的定义。

    【讨论】:

    • OP 正在尝试专门化静态方法 - 然后这将不起作用。
    猜你喜欢
    • 2011-03-05
    • 2013-04-24
    • 2021-11-10
    • 2019-08-23
    • 2012-05-24
    • 2010-10-10
    • 2012-06-25
    • 2015-04-08
    相关资源
    最近更新 更多