C#可选参数构造函数

3

是否可以为C#类定义另一个无参数构造函数?

换句话说,我有一个名为Foo的类。 我想要一个默认的构造函数 Foo()和另一个构造函数SpecialFoo()。 如果SpecialFoo()调用Foo()构造函数,我不介意。

我能做到吗?


你建议用什么语法来调用另一个构造函数?var x = new Foo(); - ta.speot.is
你为什么要这样做?听起来有点像X-Y问题 - p.s.w.g
3个回答

7

你只能有一组指定参数的构造函数,因此你无法拥有两个无参数的构造函数。

你可以拥有另一个public static Foo方法,它将是工厂方法,并返回Foo类的新实例,但要使用它,你不会使用new关键字:

class Foo
{
    public static Foo SpecialFoo()
    {
        return new Foo();
    }
}

var instance1 = new Foo();
var instance2 = Foo.SpecialFoo();

3

构造函数与方法一样,不能具有相同参数列表的重载。但是,您可以创建一个静态工厂方法,如下所示:

public class Foo
{
    public static Foo SpecialFoo() {
         ...
    }
}

这样调用:

var foo = new Foo();
var specialFoo = Foo.SpecialFoo();

一种替代方法是使用如下所示的单独构造函数:
public class Foo
{
    public Foo(bool special) : this() {
         if (special)
         {
             ...
         }
    }
}

然后像这样调用:

var foo = new Foo();
var specialFoo = new Foo(true);

当然,这并不真正算是“替代的无参构造函数”,但相比静态工厂方法,它具有一些优点。主要的是,你可以在继承类中使用和扩展它,而工厂方法则不允许。 * (实际上,你可以这样做,但需要用 new 隐藏基本工厂方法,否则会收到警告,并且在基类上隐藏静态成员通常是不好的做法。)

一个静态方法可以工作,但它会破坏开闭原则。每次需要特殊功能时,您都需要修改类。 - Dmitry S.
@DmitryS。我同意,如果Foo是可继承的,则更好的解决方案是使用单独的构造函数。我刚刚更新了我的答案,并提供了一个合适的解决方案。 - p.s.w.g

1
你可以做到这一点:

public class Foo
{
    public Foo()
    {
        // do something
    }
}

public class SuperFoo : Foo
{
    public SuperFoo() : base() // call the Foo constructor - you do not have to call base explicitely, just a more verbose example
    {
        // do something else
    }
}

1
我不喜欢这个,因为它不能扩展。 - ta.speot.is
你所说的“规模”是什么意思?多重继承是指什么? - Dmitry S.
如果您需要10个“特殊”的构造函数,则会有10个额外的类型。 - ta.speot.is
不,你定义10个子类。这并不比有10个方法更昂贵。但是带有接口的工厂可能是更好的选择。 - Dmitry S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接