从静态基类方法调用子类构造函数

发布于 2024-09-18 08:11:15 字数 823 浏览 3 评论 0原文

好的...在 Objective C 中,您可以使用“new this()”从基类中的静态方法新建子类,因为在静态方法中,“this”指的是类,而不是实例。当我第一次发现它时,这是一个非常酷的发现,并且我经常使用它。

然而,在 C# 中这是行不通的。该死!

那么...有人知道如何从静态基类方法中“新建”子类吗?

像这样的东西......

public class MyBaseClass{

    string name;

    public static Object GimmeOne(string name){

     // What would I replace 'this' with in C#?
        return new this(name); 

    }

    public MyBaseClass(string name){
        this.name = name;
    }

}

// No need to write redundant constructors
   public class SubClass1 : MyBaseClass{ }
   public class SubClass2 : MyBaseClass{ }
   public class SubClass3 : MyBaseClass{ }

SubClass1 foo = SubClass1.GimmeOne("I am Foo");

是的,我知道我可以(通常会)直接使用构造函数,但我们有一个特定的需要调用基类上的共享成员,所以这就是我问的原因。再说一遍,Objective C 让我来做这件事。希望 C# 也能做到。

那么...有人接受吗?

Ok... in Objective C you can new up a subclass from a static method in the base class with 'new this()' because in a static method, 'this' refers to the class, not the instance. That was a pretty damn cool find when I first found it and I've used it often.

However, in C# that doesn't work. Damn!

So... anyone know how I can 'new' up a subclass from within a static base class method?

Something like this...

public class MyBaseClass{

    string name;

    public static Object GimmeOne(string name){

     // What would I replace 'this' with in C#?
        return new this(name); 

    }

    public MyBaseClass(string name){
        this.name = name;
    }

}

// No need to write redundant constructors
   public class SubClass1 : MyBaseClass{ }
   public class SubClass2 : MyBaseClass{ }
   public class SubClass3 : MyBaseClass{ }

SubClass1 foo = SubClass1.GimmeOne("I am Foo");

And yes, I know I can (and normally would) just use the constructors directly, but we have a specific need to call a shared member on the base class so that's why I'm asking. Again, Objective C let's me do this. Hoping C# does too.

So... any takers?

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

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

发布评论

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

评论(2

薔薇婲 2024-09-25 08:11:15

C# 没有任何与此完全等同的东西。但是,您可以通过使用如下的泛型类型约束来解决这个问题:

public class MyBaseClass
{
    public string Name { get; private set; }

    public static T GimmeOne<T>(string name) where T : MyBaseClass, new()
    {
        return new T() { Name = name };
    }

    protected MyBaseClass()
    {
    }

    protected MyBaseClass(string name)
    {
        this.Name = name;
    }
}

new() 约束表示存在一个无参数构造函数 - 您没有,但我们将其设为私有以向消费者隐藏它。然后可以像这样调用它:

var foo = SubClass1.GimmeOne<SubClass1>("I am Foo");

C# doesn't have any exact equivalent to that. However, you could potentially get around this by using generic type constraints like this:

public class MyBaseClass
{
    public string Name { get; private set; }

    public static T GimmeOne<T>(string name) where T : MyBaseClass, new()
    {
        return new T() { Name = name };
    }

    protected MyBaseClass()
    {
    }

    protected MyBaseClass(string name)
    {
        this.Name = name;
    }
}

The new() constraint says there is a parameterless constructor - which your didn't but we make it private to hide that from consumers. Then it could be invoked like this:

var foo = SubClass1.GimmeOne<SubClass1>("I am Foo");
み零 2024-09-25 08:11:15

抱歉,你不能这样做。 C# 在道德上反对静态方法继承。 GimmeOne 方法永远不会有除 MyBaseClass 之外的任何类型,并且从 SubClass1 调用它并不重要 - 它仍然是“真正的”MyBaseClass 调用。 Reflection 库可以完成这种构造,但是除了 MyBaseClass 之外您永远不会得到任何东西。

如果您正在调用静态方法,那么您大概知道从哪个子类调用它。为每个子类创建不同的工厂方法。如果您实际上尝试通过实例执行此操作,则可能应该使用非静态虚拟工厂方法(它将自动调用函数的最派生形式,这可能就是您想要的)。

Sorry, you can't do this. C# is morally opposed to static method inheritance. That GimmeOne method will never have any type other than MyBaseClass, and calling it from SubClass1 doesn't matter- it's still "really" a MyBaseClass call. The Reflection libraries could do this construction, but you'd never get anything other than a MyBaseClass out of it.

If you're calling a static method, presumably you know which subclass you're calling it from. Create a different factory method for each subclass. If you're actually trying to do this by instance, you should probably use a non-static virtual factory method (which will automatically call the most derived form of the function, which is probably what you want) instead.

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