在静态方法中引用"self"类型 - C#

m1t*_*tk4 14 c#

我试图创建一个静态方法,它将返回类的实例,如:

class A {
   public static A getInstance() {
      return new A();
   }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,如果我有一个派生自A的子类B,我希望B.getInstance()返回B的实例,而不是A.在PHP世界中,你可以使用关键字"self"来引用到你自己的类型,所以你的getInstance()看起来像:

public static function getInstance() {
   return new self();
}
Run Code Online (Sandbox Code Playgroud)

最好的方法是什么?

Jon*_*eet 8

基本上你不能.如果对仅在基类中声明的静态成员的调用实际上是根据派生类表示的,则如下所示:

// Urgh
Encoding ascii = ASCIIEncoding.ASCII;

// Worse yet (and yes, I've seen this)
Encoding ascii = UTF8Encoding.ASCII;
Run Code Online (Sandbox Code Playgroud)

然后编译器以静默方式将其转换为:

Encoding ascii = Encoding.ASCII;
Run Code Online (Sandbox Code Playgroud)

原始源包含派生类的名称的事实不会保留在已编译的代码中,因此无法在执行时对其执行操作.


Geo*_*ett 7

如何使用泛型提供生成类型:

public static T getInstance<T>() where T : A, new()
{
    return new T();
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*sik 5

您可以隐藏等以某种方式覆盖继承类型中的 getInstance 方法,如下所示:

class B : A {
    public static new B getInstance() {
        return new B();
    }
}
Run Code Online (Sandbox Code Playgroud)

new关键字指定继承方法的隐藏是故意的,否则,你得到一个编译器警告。

完整示例:

using System;

class A {
    public static A getInstance() { return new A(); }
    public void PrintSelf() {Console.WriteLine(this.GetType().Name);}
}

class B : A {   
    public static new B getInstance() {
        return new B();
    }
}

public class MyClass {
    public static void Main() {
        A a = A.getInstance();
        B b = B.getInstance();
        a.PrintSelf();
        b.PrintSelf();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请记住,如果您忘记在任何地方执行此操作,编译器将不会警告您……您只会默默地获得“错误”类型。 (3认同)