c# - c# 中只读属性的对象初始化器
问题描述
如果你有课:
class Foo {
Bar Bar { get; } = new Bar();
}
class Bar {
string Prop {get; set; }
}
您可以使用对象初始化,例如:
var foo = new Foo {
Bar = { Prop = "Hello World!" }
}
如果你有课
class Foo2 {
ICollection<Bar> Bars { get; } = new List<Bar>();
}
你可以写
var foo = new Foo2 {
Bars = {
new Bar { Prop = "Hello" },
new Bar { Prop = "World" }
}
}
但是,我想写一些类似的东西
var items = new [] {"Hello", "World"};
var foo = new Foo2 {
Bars = { items.Select(s => new Bar { Prop = s }) }
}
但是,上面的代码不能编译:
无法将 IEnumerable 分配给 Bar
我不能写:
var foo = new Foo2 {
Bars = items.Select(s => new Bar { Prop = s })
}
属性栏是只读的。
这个可以存档吗?
解决方案
如果您阅读实际的编译器错误(以及集合初始化程序的文档),您会发现集合初始化程序只是Add()
调用的语法糖:
CS1950:最好的重载集合初始化方法
System.Collections.Generic.ICollection<Bar>.Add(Bar)
有一些无效参数CS1503:参数
#1
无法将System.Collections.Generic.IEnumerable<Bar>
表达式转换为类型Bar
所以语法SomeCollection = { someItem }
将被编译为SomeCollection.Add(someItem)
. 而且您不能添加IEnumerable<Bar>
到Bar
s 的集合中。
您需要手动添加所有项目:
foreach (bar in items.Select(s => new Bar { Prop = s }))
{
foo.Bars.Add(bar);
}
或者,给定更短的代码是您的目标,在Foo2
的构造函数中执行相同的操作:
public class Foo2
{
public ICollection<Bar> Bars { get; }
public Foo2() : this(Enumerable.Empty<Bar>()) { }
public Foo2(IEnumerable<Bar> bars)
{
Bars = new List<Bar>(bars);
}
}
然后你可以像这样初始化 Foo2:
var foo = new Foo2(items.Select(...));
对于@JeroenMostert 假设的对集合初始化器语法的有趣滥用,您可以使用扩展方法:
public static class ICollectionExtensions
{
public static void Add<T>(this ICollection<T> collection, IEnumerable<T> items)
{
foreach (var item in items)
{
collection.Add(item);
}
}
}
这允许这样做:
public class Foo
{
public ICollection<string> Bar { get; } = new List<string>();
}
var foo = new Foo
{
Bar = { new [] { "foo", "bar", "baz" } }
};
但这太恶心了。
推荐阅读
- botframework - Bot 连接器 API:直接向 aadObjectId 发送消息
- flutter - 来自 API 的 JSON 数据未显示在下拉列表中
- python - Python3 print 语句打印 0 而不是函数的实际返回值
- javascript - 将 jquery 插件延迟几秒钟,滚动 y 或退出意图
- swiftui - 为什么不显示缓存提示?
- ruby-on-rails - ElasticBeanstalk Ruby PostDeploy 脚本任务不可能
- c++ - 有没有办法根据openCV C++中的环境自动调整亮度和对比度?
- pandas - 在线性时间内执行 csv 清理
- flutter - chart_flutter:如何使用 Flutter Chart 做折线图重叠 y 轴标签?
- string - 使用多个字符串和日期条件定位文件