构造函数可以返回子类吗?

9

以下是客户端代码:

var obj = new Class1();

有没有办法修改Class1的构造函数,使其实际返回子类(或其他替代实现)?

我希望obj获得两种不同的实现,具体取决于某些条件。显然,我可以改用工厂或DI框架,但如果可能的话,我想避免更改客户端代码。

我认为答案是否定的,但我想知道是否有一些聪明的方法可以实现这一点。


6
我们正在考虑添加一个名为“extension new”的功能,它将实质上允许您创建一个静态工厂方法,当使用“new”操作符时调用该方法,就像使用“.”操作符时调用扩展方法一样。这将是一个工厂的简洁语法糖。如果您有一个真正棒的场景可以应用这种模式,我很想看到一个例子。 - Eric Lippert
1
@Eric:虽然这不是一个特定于C#的例子,但我遇到了一个在C++中非常有用的情况。我正在开发一个跨平台库,如果一个平台无关的ABC能够从它的构造函数返回一个特定于平台的派生类实例,那将非常有用。我相信在使用C#进行开发时也会遇到类似的情况。 - Mac
@Eric Lippert - 我有一个真实世界的情景给你!http://blog.hackensplat.com/2010/09/construct-something-else-c.html - billpg
4个回答

9
您可以使用工厂方法替换构造函数,并根据参数返回任何您喜欢的内容:
public Class2 : Class1 {}

public static Class1 CreateClass1(bool returnDerivedClass)
{
    if (returnDerivedClass)
    {
        return new Class2();
    }
    else
    {
        return new Class1();
    }
}

4

这是不可能的。

巧妙的解决方法包括用一个static函数替换构造函数或者(不推荐)使用一个基类的包装器,创建不同的包装类。


有任何示例吗? - Nick Kovalsky

0

使用注入库。下面的链接提供了一个很棒的注入库列表,以及它们性能的比较。

http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison

然而,我认为性能很少是你选择一个注入库的标准,大多数应用程序不会实例化这个人在测试中使用的对象数量。我正在使用NInject,它做得很好,但是如果我要开始另一个项目,我可能会尝试一下simpleinjector,它似乎具有我在NInject中使用的所有功能,并且在性能比较方面表现良好。


0
对于这样的事情,您需要查看工厂模式。此外,根据您的需求,我建议查看通用方法以减少耦合度。在程序中调用类的构造函数是最难处理的耦合,会使像交换实现等操作变得十分困难,正如您自己发现的那样。
阅读关于"控制反转"和"依赖注入"的内容,也许这才是您真正寻找的。 这里可以找到一个很好的库。

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