参数和构造函数

时间:2013-06-07 19:00:26

标签: c#

我已经在 Stack Overflow Microsoft Developer Network 和几个博客中阅读了很多详细的内容。普遍的共识是“A Constructor不应包含大量参数。”所以遇到这个让我思考 -

  • 初始问题:我的应用程序包含大约15个在整个应用程序中不断使用的变量。 我提出的解决方案是,我将创建一个将值注入Properties的类。

所以这看起来效果很好,它使我的生活变得非常轻松,因为我可以通过objectclass传递到另一个Constructor,而不必将所有这些变量分配给每个method。除此之外导致另一个问题 -

public class ServerParameters
{
    // Variable:
    private string template;
    private string sqlUsername;
    private string sqlPassword;
    private string sqlDatabase;
    private string sqlServer;

    public ServerParameter(string _template, string _sqlDatabase, string _sqlServer, 
string _sqlUsername, string _sqlPassword)
    {
        template = _template;
        sqlUsername = _sqlUsername;
        sqlPassword = _sqlPassword;
        sqlDatabase = _sqlDatabase;
        sqlServer = _sqlServer;
    }

// Link the private strings to a group of Properties.

}

因此Constructor已经变得非常臃肿 - 但现在我需要实现更多参数

  • 问题二:所以我有一个臃肿的Constructor并且通过实现其他不完全适合这个特定Class的项目。 我的解决方案是创建subclasscontainer来保存这些不同的classes但能够使用这些classes

您现在看到了困境,这引起了所有重要问题 - 当您只能继承一次时,如何构建一个容纳所有这些子类的容器?

为什么不在构造函数中使用这么多参数,为什么它确实不好?

我对如何实现Container的想法,但我觉得我做错了 - 因为当我尝试使用其中一些时,我经常得到 Null Reference Exception {{ 1}}。

Parameters

我认为这是因为内部类本身实际上没有获得那些分配的变量,但我完全迷失了实现目标的最佳方法 -

4 个答案:

答案 0 :(得分:3)

“不在构造函数中工作”的主要目的是避免在创建对象时产生副作用,并且它会执行大量工作,这些工作可能会意外地影响全局状态,甚至需要很长时间才能完成可能会破坏来电者的代码流。

在你的情况下,你只是设置参数值,所以这不是“不做工作”的意图,因为这不是真的有效。最终容器的设计取决于您的要求 - 如果您可以接受在class(或struct)上设置的变量属性列表,那么在构建时可能需要initializer对象更合适。

假设您想要获得所有属性,并且您希望像问题中那样分组,我会构建类似于:

的内容
public class Properties 
{
    public ServerProperties Server { get; private set; }
    public CustomerProperties Customer { get; private set; }

    public Properties(ServerProperties server, CustomerProperties customer)
    {
         Server = server;
         Customer = customer;
    }
 }

我将离开ServerPropertiesCustomerProperties的实现,但它们遵循相同的实现模式。

答案 1 :(得分:1)

这当然是一个偏好问题,但我总是给我的构造函数提供他们需要的所有参数,以便我的对象具有基本功能。我不认为5个参数是膨胀的,并且添加容器来传递参数在我看来比添加更多参数更加膨胀。通过新的膨胀我的意思是你可能会有一个新的文件,新的类和新的导入。调用代码必须编写更多using指令并链接到需要正确导出的正确库。

为参数掩码添加一个包装类是真正的问题,你的类可能太复杂了,它没有解决它并且通常会加剧它。

答案 2 :(得分:0)

您可以在构造函数中包含任何数量的参数。只是如果你有太多(多少太多了?这真的是主观的),那么制作一个新类的实例就会变得越来越难。

例如,假设您有一个包含30个成员的类。其中27个可以为空。如果强制它为构造函数中的每个成员接收一个值,您将获得如下代码:

Foo bar = new Foo(p1, p2, p3, null, null, null, null, null, null /*...snip*/);

写三个参数构造函数的方法很难写,而且不太可读。

IMO,这是您应该在构造函数中收到的内容:

  • 首先,您的实例绝对需要才能工作。它需要有意义的东西。例如,与数据库连接相关的类可能需要连接字符串。
  • 在上面提到的那些之后,你可能有重载,接收最有用的东西。但不要在这里夸大。

其他所有内容,您都可以通过set访问者在属性中让以前使用您的代码集的任何人。

答案 3 :(得分:0)

在我看来,您可以使用依赖注入容器,例如UnityCastle Windsor