【发布时间】:2020-10-30 15:26:21
【问题描述】:
我的一些 C# 类在设计上没有默认构造函数。我习惯于声明一个空的私有默认构造函数,以防止我的类的客户端使用编译器提供的默认构造函数。
现在我在我的 C# 项目 (#nullable enable) 中启用了不可为空的引用,但这不再有效,我参考下面的 CS8618 警告:
#nullable enable
public sealed class Operation
{
private readonly CancellationTokenSource _cts;
private Operation()
{
// Warning CS8618 Non-nullable field '_cts' is uninitialized.
// Consider declaring the field as nullable.
//_cts = null!;
}
public Operation(CancellationToken token)
{
_cts = CancellationTokenSource.CreateLinkedTokenSource(token);
}
...
}
看来,我现在要么必须初始化所有不可为空的字段(我想是使用 null-forgiving null!?),要么完全删除非默认构造函数。解决这个问题的优雅方法是什么?
更新以解决 cmets:
也许我不够清楚,所以我会尝试解决这个问题。我很清楚,如果我没有明确声明,C# 会提供一个默认的public 无参数构造函数。这正是我声明它并使其成为private 的原因。 防止使用无参数构造函数构造Operation 类型的对象。
我还有一个工厂类:
public static class OperationFactory
{
public static Operation* CreateOperation(CancellationToken token)
{
return new Operation(token);
}
}
我班的客户可以这样做:
var operation = new Operation(token)
或
var operation = OperationFactory.CreateOperation(token)
但他们不允许这样做:
// this would create an object in invalid state
var operation = new Operation();
所以以前,要强制执行这些规则,我只需声明一个空的 private parameterless constructor: private Operation() {}。
现在有了#nullable enable,我不能再有一个 empty 私有构造函数了。我现在必须在私有构造函数(仍然从未使用过,所以这是一个缺点)和公共构造函数中初始化所有不可为空的引用字段。
由于本质上从未使用私有构造函数,我认为可能有一种优雅的方法可以避免重复此类初始化代码。有吗?
【问题讨论】:
-
如果只删除默认构造函数会怎样?
-
不幸的是,要求最优雅的方式是徒劳的,因为这变成了一个时尚感问题。找出完成任务的方法并选择你最喜欢的
-
请先解释一下为什么要添加无参数构造函数。当您提供任何构造函数时,编译器将不再生成默认的无参数构造函数,并且无法使用
new实例化该类,除非使用您提供的显式构造函数之一。您的问题似乎是代码中有一个构造函数的直接结果,它无论如何都不应该有。完全不清楚为什么这个问题需要解决。 -
@PeterDuniho,我首先添加了
private无参数构造函数,因此我的库的用户无法选择以这种方式创建我的类的实例。我希望他们始终使用需要参数的构造函数。
标签: c#