为了账号安全,请及时绑定邮箱和手机立即绑定

具有不可变存储的只读字段的类的构造函数

具有不可变存储的只读字段的类的构造函数

C#
慕虎7371278 2022-10-23 15:17:08
假设我们有以下简单的类。请注意,唯一的字段是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);现在,我可能还想要一个可以构建Abc给定 an的构造函数IEnumerable<int>: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)可能看起来像是在Abc用单个元素 ( item) 创建一个。但是如果item实际上是一个IEnumerable<int>具有多个项目的,上面的第二个构造函数将被调用。如果您查看 Microsoft ImmutableListAPI,它们实际上调用ImmutableList.CreateRange了类似于上面的第二个构造函数的静态方法。这很好,因为我们避免了上述视觉模糊。好的,让我们开始为我们的Abc类绘制一个类似构造函数的简单实现:public static Abc CreateRange(IEnumerable<int> ls){    elts = ImmutableList.CreateRange(ls);    ...}当然,我们在这里遇到了一个问题,因为该elts字段是readonly并且不能通过此静态方法初始化:CreateRange那么,为我们的课程实现的好方法是Abc什么?
查看完整描述

2 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

设置的唯一方法elts是调用 Abc 的构造函数。

修饰符保证设置变量的readonly唯一方法是在初始化期间readonly int i=0;或在构造函数中。

该错误是由静态方法无法访问 的实例引起的Abc,尽管您仍然无法修改它,因为它是readonly.

试试这个:

public static Abc CreateRange(IEnumerable<int> ls){
   return new Abc(ls);}


查看完整回答
反对 回复 2022-10-23
?
撒科打诨

TA贡献1934条经验 获得超2个赞

我相信 SLaks 的建议是创建一个私有构造函数并从静态方法调用它:

private Abc(IEnumerable<int> ls) => elts = ImmutableList.CreateRange(ls);
public static Abc CreateRange(IEnumerable<int> ls) => new Abc(ls);

这样,创建实例的唯一方法(没有反射)Abc是使用静态方法,假设您没有任何公共构造函数。


查看完整回答
反对 回复 2022-10-23
  • 2 回答
  • 0 关注
  • 61 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信