静态构造方法与构造函数

4

在.NET框架中,我经常看到一种用静态函数替换构造函数的惯用语法,以创建一个新对象。

例如,在BigInteger中没有接受字符串参数的构造函数,因此无法使用以下方法:

BigInteger i = new BigInteger("1000000103453543897");

但是有一个静态的Parse函数。
BigInteger i = BigInteger.Parse("1000000103453543897");

为什么经常选择这样的类设计?

我唯一能想到的是减少创建和销毁对象的数量。那是不是主要原因呢?还是有其他原因?

BigInteger(string value)
{
  BigInteger result = new BigInteger(); // this one just returned in a Parse function

  // compute bigint

  // copy result to this
  data = new uint[maxLength];
  for (int i = 0; i < result.Length; i++)
    data[i] = result.data[i];

  Length = result.dataLength;  
}
3个回答

3

可能有许多原因——研究“工厂方法模式”。

以您的示例为例——许多人认为在/从构造函数中调用重要逻辑是一种不好的实践(除非它是一个缺少参数)。使用工厂方法允许在对象构建时保证实现运行,但不在构造函数中运行。


2
没有接受字符串的构造函数。从技术上讲,你完全可以这样做。设计者选择不复制已经存在且没有实用价值的代码 - 这只是一行代码,更清晰地表达了你要做什么,减少了传递错误类型的错误数量等等。
这也使它与其他没有非默认构造函数的数字类型保持一致(你不能说int i = new int(4));
最重要的是 - 这样一个构造函数的价值需要超过实现、测试、文档化和发布新功能的成本。

但是你可以new int(),所以它看起来int有一个构造函数。(虽然它实际上不是一个构造函数,它只是将值类型初始化为其默认值。) - svick
@svick 是的 - 我在我的回答中澄清了这一点。 - D Stanley

1

参见 @Moho 的回答,工厂方法模式。

我个人认为 BigInteger.Parse 更好。在这种情况下,您有一个值,即一个字符串,并希望将其转换为大数。带有字符串参数的构造函数不告诉你会发生什么。你只知道它可能只是用字符串做 Console.WriteLine 而已,而不是其他更重要的事情。而 Parse 则告诉了你更多信息...


我认为构造函数的隐含语义非常清晰:根据给定的参数创建给定类型的值。这当然不包括使用参数执行 WriteLine()。虽然 Parse() 更清晰,因为它解释了参数实际意义。 - svick

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