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; }

但是由于您无法更改源代码,您所能做的就是手动将项目添加到只读 属性(即执行集合初始化程序的工作)。