【发布时间】:2019-03-14 02:11:32
【问题描述】:
假设我们有以下简单的类。请注意,唯一的字段是readonly,用于ImmutableList<int>:
class Abc
{
readonly ImmutableList<int> elts;
public Abc(params int[] ls) => elts = ImmutableList.CreateRange(ls);
}
鉴于所示的构造函数,很容易从一些ints 创建一个实例:
var result_a = new Abc(10, 20, 30);
现在,我可能还想要一个可以在给定IEnumerable<int> 的情况下构建Abc 的构造函数:
public Abc(IEnumerable<int> ls) => elts = ImmutableList.CreateRange(ls);
所以我们的类现在看起来像这样:
class Abc
{
readonly ImmutableList<int> elts;
public Abc(params int[] ls) => elts = ImmutableList.CreateRange(ls);
public Abc(IEnumerable<int> ls) => elts = ImmutableList.CreateRange(ls);
}
这确实有效:
var ls = new[] { 10, 20, 30 };
var result_b = new Abc(ls);
但是,这个构造函数有点别扭,因为乍一看,是这样的:
new Abc(item)
可能看起来它正在创建一个带有单个元素 (item) 的 Abc。但是如果item实际上是一个具有多个项目的IEnumerable<int>,则会调用上面的第二个构造函数。
如果您查看 Microsoft ImmutableList API,他们实际上有一个名为 ImmutableList.CreateRange 的静态方法,类似于上面的第二个构造函数。这很好,因为我们避免了上述视觉模糊。
好的,让我们开始为我们的Abc 类绘制一个类似构造函数的简单实现:
public static Abc CreateRange(IEnumerable<int> ls)
{
elts = ImmutableList.CreateRange(ls);
...
}
当然,我们在这里遇到了一个问题,因为elts 字段是readonly 并且不能通过这个静态方法初始化:
那么,为我们的Abc 类实现CreateRange 的好方法是什么?
【问题讨论】:
-
让它调用一个(私有的?)构造函数。
-
@SLaks 感谢您的建议!看起来约翰根据您的建议提供了答案。看起来不错!
-
如果
elts已经是私有的,为什么还要将它设为只读? -
@shingo 如果不出意外,这是告诉未来的维护者即使
Abc类中的代码也不应该在构造类之后替换elts的好方法。