为什么集合初始化会忽略访问修饰符
本文关键字:访问 集合 初始化 为什么 | 更新日期: 2023-09-27 18:34:53
从
这个答案中生成,出现了一些似乎没有意义的代码:
class Program
{
static void Main(string[] args)
{
var t = new Testing
{
ListOfStrings =
{
"hello",
"goodbye"
}
};
Console.ReadKey();
}
}
public class Testing
{
public List<string> ListOfStrings { get; private set; }
public Testing()
{
ListOfStrings = new List<string>();
}
}
乍一看,人们会认为这段代码不会编译:毕竟ListOfStrings
应该有一个私有的 setter,并且不应该以这种方式分配给它。
但是,此代码编译并运行良好,并且t.ListOfStrings
分配了值。
为什么此集合初始化忽略私有资源库?
在您的示例中,您实际上并没有设置该属性。
C# 足够聪明,知道您正在使用 ICollection,可以使用添加、删除、清除等公开修改。 您正在执行的操作相当于以下内容:
t.AddRange(new string[] { "hello", "goodbye" });
如果您实际上尝试这样做,它将不起作用:
var t = new Testing
{
ListOfStrings = new List<string>(),
};
编辑:
由于您可能想知道如何将集合公开为只读,因此可以通过将其公开为 IEnumerable 来执行此操作:
public class Testing
{
private List<string> _listOfStrings;
public IEnumerable<string> MyStrings
{
get
{
foreach (var s in _myStrings)
yield return s;
}
}
public Testing()
{
_listOfStrings = new List<string>();
}
}
您也可以创建一个只读集合,但我发现这更令人困惑。 如果将其公开为 IEnumerable,则类的使用者可以枚举项,而无法添加或删除项。
为什么此集合初始化忽略私有资源库?
其实不然。此集合初始化语法:
var t = new Testing
{
ListOfStrings =
{
"hello",
"goodbye"
}
};
实际上由编译器转换为如下所示的内容:
var t = new Testing();
t.ListOfStrings.Add("hello");
t.ListOfStrings.Add("goodbye");
如您所见,ListOfStrings
实际上并没有被分配一个新值......