-1 在 C# 列表的索引中

-1 in the index of a list in C#

我最近在我们的应用程序中遇到了以下代码

var updateDefinition = new UpdateDefinitionBuilder<OverviewProfile>()
            .Set(a => a.Advisors[-1].IsCurrent, advisor.IsCurrent);

在上面的代码中,Advisors 是一个 ListUpdateDefinitionBuilder 来自 MongoDB 驱动程序。

你能告诉我-1在列表索引中的用法吗?

编辑comments/answers

OverviewProfileclass如下:

public class OverviewProfile: BaseInvestorProfile
{
    //Other properties

    public List<Advisor.View.Advisor> Advisors { get; set; }
    public OverviewProfile(int id): base(id)
    {
        Advisors = new List<Advisor.View.Advisor>();
    }
}

这是工作代码。此代码根据条件将数据更新到 mongo 数据库。此 class 中没有其他方法,只有其他属性。

这是一个 class,但是对于多个 class 的属性也有相同的用法,甚至当我们添加一个新的 List 属性 并检查时,它工作正常。

如果a.Advisors确实是一个List<T>,就没有用了。这将抛出一个 ArgumentOutOfRangeException.

更有可能的是,这是一些自定义 class 或 List<T> 的实现,其中传递到索引器的 -1 值类似于 'default' 值.

不管是什么,我认为这是一个糟糕的设计,应该避免。

您正在使用期望 ExpressionUpdateDefinitionBuilder<T>.Set 的重载。此表达式不直接编译和执行,而是转换为本机 mongodb 语法,并用作 mongo 数据库查询的一部分(与 Entity Framework 或其他 ORM 将表达式转换为 SQL).这基本上表示 "update all overview profiles and set IsCurrent flag of first advisor that matches criteria to advisor.IsCurrent value"。因为 mongodb 允许负索引(意思是 - 相对于集合的末尾)- C# mongodb 驱动程序可以将您的表达式转换为有效的 mongodb 查询(但请参阅下面的更新)。

更新。如前所述 here, -1 still has special meaning for mongodb C# driver. It will be converted to positional update operator $:

the positional $ operator acts as a placeholder for the first element that matches the query document

例如:

var updateDefinition = new UpdateDefinitionBuilder<OverviewProfile>()
    .Set(a => a.Advisors[-1].IsCurrent, false);

colleciton.UpdateOne(c => c.Advisors.Any(r => r.IsCurrent), updateDefinition);

将转换为类似:

"updates": [{
        "q": {
            "Advisors": {
                "$elemMatch": {
                    "IsCurrent": true
                }
            }
        },
        "u": {
            "$set": {
                "Advisors.$.IsCurrent": false // <- your expression
            }
        }
    }
]

但是,关于 mongodb 中相对于收集结束的负索引意义的观点仍然成立,因为除了 -1(例如 -2)之外的任何其他负索引将被转换为查询这个:

{ "$set" : { "Advisors.-2.IsCurrent" : false} }