C# 初始化只获取具有动态对象范围的列表属性
C# initialize get only list propetry with dynamic range of objects
我有以下对象声明:
DatabaseTableElm exportTable = new DatabaseTableElm()
{
Columns = columnCt ,
Keys = {
new DatabaseKeyCt()
{
/* this way of setting columns works */
Columns = { new DatabaseKeyColumnCt() { Name = "ObjectId", SortOrder = SortOrderEnum.Descending } },
Type = DatabaseKeyTypeEnum.Primary
},
new DatabaseKeyCt()
{
/* this way of setting columns does not work */
Columns = list.Keys.Select(x => new DatabaseKeyColumnCt() { Name = x, SortOrder = SortOrderEnum.Ascending } ).ToList(),
Type = DatabaseKeyTypeEnum.Unique
}
},
Name = "test",
Schema = "dbo",
Temporal = true
};
Columns 是 属性 在 class DatabaseKeyCt 中定义的
public List<VaultSchemaObjects.Tns.DatabaseKeyColumnCt> Columns { get; } = new List<VaultSchemaObjects.Tns.DatabaseKeyColumnCt>();
在第一条评论中您可以看到,尽管只是获取 属性,我仍然可以使用“静态”值数组对其进行初始化。在第二条评论中,我尝试做同样的事情,但现在有一个对象列表。但那时我收到一条错误消息,指出列是只读的。
我的假设是,在第一条评论中,数组被接受为列表的某种初始集合。但是在第二条评论中,它认为我正在尝试分配一个新列表,但它失败了。
我无法更改 class,因此向列 属性 添加 setter 的解决方案无效。
能否修复第二条评论处的行,以便我可以从我的 linq 表达式填充列表?
第一个使用现有的 Keys
值并调用 Add
。
第二个尝试在构造函数之外对只读 Keys
进行赋值。
不,您不能在不更改源代码的情况下初始化只读属性
TLDR; 在第一种情况下,您有 Collection Initializer,它实际上被编译为对已创建的集合实例的一堆 Add
方法调用。所以如果你有 属性
public List<int> Values { get; } = new List<int>();
属性 已用空列表初始化。当您在此 属性
上使用集合初始值设定项时
Values = { 1, 2 }
编译为
Values.Add(1);
Values.Add(2);
如果您尝试将集合初始值设定项应用于新列表并将其分配给 属性:
,您会看到不同之处
Values = new List<int> { 1, 2 } // Fails as your second attempt
这个问题可以用 Init Only Setters 解决,但尚未实现(据我所知)。解决方案将是:
public List<int> Values { get; init; }
但是由于您无法更改源代码,您所能做的就是手动将项目添加到只读 属性(即执行集合初始化程序的工作)。
我有以下对象声明:
DatabaseTableElm exportTable = new DatabaseTableElm()
{
Columns = columnCt ,
Keys = {
new DatabaseKeyCt()
{
/* this way of setting columns works */
Columns = { new DatabaseKeyColumnCt() { Name = "ObjectId", SortOrder = SortOrderEnum.Descending } },
Type = DatabaseKeyTypeEnum.Primary
},
new DatabaseKeyCt()
{
/* this way of setting columns does not work */
Columns = list.Keys.Select(x => new DatabaseKeyColumnCt() { Name = x, SortOrder = SortOrderEnum.Ascending } ).ToList(),
Type = DatabaseKeyTypeEnum.Unique
}
},
Name = "test",
Schema = "dbo",
Temporal = true
};
Columns 是 属性 在 class DatabaseKeyCt 中定义的
public List<VaultSchemaObjects.Tns.DatabaseKeyColumnCt> Columns { get; } = new List<VaultSchemaObjects.Tns.DatabaseKeyColumnCt>();
在第一条评论中您可以看到,尽管只是获取 属性,我仍然可以使用“静态”值数组对其进行初始化。在第二条评论中,我尝试做同样的事情,但现在有一个对象列表。但那时我收到一条错误消息,指出列是只读的。
我的假设是,在第一条评论中,数组被接受为列表的某种初始集合。但是在第二条评论中,它认为我正在尝试分配一个新列表,但它失败了。
我无法更改 class,因此向列 属性 添加 setter 的解决方案无效。
能否修复第二条评论处的行,以便我可以从我的 linq 表达式填充列表?
第一个使用现有的 Keys
值并调用 Add
。
第二个尝试在构造函数之外对只读 Keys
进行赋值。
不,您不能在不更改源代码的情况下初始化只读属性
TLDR; 在第一种情况下,您有 Collection Initializer,它实际上被编译为对已创建的集合实例的一堆 Add
方法调用。所以如果你有 属性
public List<int> Values { get; } = new List<int>();
属性 已用空列表初始化。当您在此 属性
上使用集合初始值设定项时Values = { 1, 2 }
编译为
Values.Add(1);
Values.Add(2);
如果您尝试将集合初始值设定项应用于新列表并将其分配给 属性:
,您会看到不同之处Values = new List<int> { 1, 2 } // Fails as your second attempt
这个问题可以用 Init Only Setters 解决,但尚未实现(据我所知)。解决方案将是:
public List<int> Values { get; init; }
但是由于您无法更改源代码,您所能做的就是手动将项目添加到只读 属性(即执行集合初始化程序的工作)。