我的所有参数都应该在构造函数中吗?

时间:2011-08-24 17:22:49

标签: c# .net constructor arguments

我有一个班级StreamCopyOperation,它为我提供了诸如复制操作的平均速度和其他信息之类的东西。

现在我有一个看起来像

的构造函数
public StreamCopyOperation(Stream source, Stream target, int bufferSize, int updateInterval)
{
    //Initialize values
}

和方法

public void CopyStream()
{
    //Copy the streams, send the progress updates, etc...
}

现在我不知道所有参数是否应该在构造函数中,或者流应该在这样的方法中传递:

public void CopyStream(Stream source, Stream target)
{
    //Copy the streams, send the progress updates, etc...
}

,构造函数只获取缓冲区大小和传递的更新间隔。 或者也许所有内容都应该在CopyStream方法中。

是否有类似最佳做法的事情,或者这只是一个设计决定?

7 个答案:

答案 0 :(得分:4)

我认为这是一个基于您对课程使用方式的设计决定。

如果它是一次使用类型的类,那么可能所有参数都应传递给构造函数,然后设置任何其他属性,然后调用CopyStream(不带参数)。

但是,如果您希望更改流参数,则不要将它们传递给构造函数,并将值传递给CopyStream方法。

最后,如果它真的更像是一次使用类型的类,那么也许您应该将该类视为static类并且CopyStream是静态的 - 为您节省一行代码并使类更像是一个帮助类型。

希望这有帮助!

答案 1 :(得分:2)

在我看来,这取决于StreamCopyOperation对象的生命周期......

特别是,由于流对象通常(总是?)是一次性的并且绑定到某些系统资源,我希望尽可能少地保留它们,所以我会考虑采用参数化方法。

如果StreamCopyOperation仅绑定到流本身的生命周期,则第一种方法是合适的。

但是如果你想让操作对象保持更长时间(例如,因为它连接到UI),那么我将使用参数化函数方法并进入更多静态“辅助类”。

答案 2 :(得分:1)

这取决于您期望CopyStream的使用方式。这是经常使用的东西吗?这将建议使用CopyStream方法的方法参数。如果它被设计为一次性调用,那么在启动类型的新实例时使用构造函数参数。

答案 3 :(得分:0)

如果你将在类范围中使用那些Stream,比如其他方法,最好将它们作为构造函数参数传递,并将它们分配给在类范围内声明的变量,否则不需要将它们传递给构造函数和建议使用第二种CopyStream方法。

希望这有帮助。

答案 4 :(得分:0)

我几乎认为这是一个设计决定。

如果没有为多个源和/或目标重用单个CopyStreamOperator实例,我可能会在构造函数中传递所有必需的值来创建一个知道它需要知道的所有内容的对象。然后可以验证输入值以确保您的操作员永远不会处于无效状态。

然后将无参数CopyStream()方法重命名为Run()Execute()

答案 5 :(得分:0)

我会考虑将默认值用于不那么重要的细节,并在类中提供属性来设置或获取它们的值:

private const int DEF_BUFFER = 100;
private const int DEF_INTERVAL = 10;

public StreamCopyOperation(Stream source, Stream target)
{
   //Initialize values
   this.BufferSize = DEF_BUFFER;
   this.UpdateInterval = DEF_INTERVAL;
} 

public int BufferSize { get; set;} // or use a private member inside, if needed

public int UpdateInterval { get; set;} // or use a private member inside, if needed

答案 6 :(得分:0)

我的设计指南是只要求用户提供构造函数,以便构造实例是绝对必要的。也许用户不希望进度更新。也许当用户想要构造实例并连接进度事件时,他们还没有两个流。

当然,您可以提供方便的构造函数重载(或可选参数),以便在更多情况下更容易使用您的类(但这些可以推迟到'构造方法',例如TimeSpan.FromMinutes(5))。但请记住,构造函数只是简单地创建和初始化您的类型及其所有子系统,使其处于可用,一致的状态,随时可以进行用户的出价。

当然,例外是不可变类型,您必须在构造期间指定所有参数。通常不可变类型相当简单,因此这不是问题。如果它们更复杂并且构造函数参数的数量越来越失控,您可以使用一个可变的“初始化程序说明符”对象,该对象包含如何初始化不可变对象的所有各种配置,但更容易使用,因为它有可变的属性。