2010-02-28 83 views
7

考虑下面的客户端代码:可以构造函数返回一个子类?

var obj = new Class1(); 

有什么办法修改的Class1,而不是构造器,这样它实际上将返回一个子类(或其他一些替代实现)?

我想OBJ得到两种不同的实现方式之一,这取决于一些条件。显然,我可以更改为使用工厂或DI框架,但如果可能的话,我想避免更改客户端代码。

我认为答案是否定的,但我不知道是否有使这种情况发生的一些聪明的办法。

+4

我们正在考虑增加一个功能,“拓新”,这将从根本上让你做出一个静态工厂方法所使用的“新”操作时会被调用,就像扩展方法被调用时的“”运算符被使用。这将是一个很好的工厂语法糖。如果你有一个非常棒的场景,这种模式会很有用,我很乐意看到一个例子。 – 2010-02-28 20:26:34

+1

@Eric:虽然它不是一个特别的C#示例,但我遇到过这种情况,在C++中会很有用。我正在开发一个跨平台的库,它对于一个平台不可知的ABC能够从它的构造函数中返回一个特定于平台的派生类实例非常有用。我确信使用C#开发时必定会遇到类似的情况。 – Mac 2010-03-09 22:01:31

+0

@Eric Lippert - 我有一个真实的场景给你! http://blog.hackensplat.com/2010/09/construct-something-else-c.html – billpg 2010-09-13 11:29:44

回答

4

这是不可能的。

巧妙的解决方法包括使用围绕基类的包装用static功能替换构造或(不推荐),以及创建不同包裹的类。

8

您可以替换工厂方法构造,并返回任何你喜欢的,这取决于参数:

public Class2 : Class1 {} 

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

对于这样的事情,你想看看工厂模式。另外,根据您的需要,我建议您查看减少耦合的一般方法。您对该类的构造函数的调用是您在程序中可能遇到的最困难的耦合,并让您像执行自己发现一样轻松地将实现交换出去。

阅读有关“控制反转”和“依赖注入”,也许这就是你真正寻找。

一个很好的库可以发现here

0

使用注射库。下面的链接呈现喷射库的大名单在那里,他们的表现

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

我会建议不过相比性能是你很少会选择在注射库中的标准,大多数应用程序将不能实例这个家伙在他的测试中使用的对象的数量。我正在使用NInject来完成这项工作,但是如果我要开始另一个项目,我可能会给simpleinjector一个去,它似乎具有我在NInject中使用的所有功能,并且在性能比较中表现良好。

相关问题