-1 in the index of a list in C#
我最近在我们的应用程序中遇到了下面这段代码
1 2
| var updateDefinition = new UpdateDefinitionBuilder <OverviewProfile >()
.Set(a => a .Advisors[-1].IsCurrent, advisor .IsCurrent); |
在上面的代码中,Advisors是List,UpdateDefinitionBuilder来自mongodb驱动程序。
你能告诉我清单索引中-1的用法吗?
在以下评论/答案之后编辑
OverviewProfile类如下:
1 2 3 4 5 6 7 8 9 10
| 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 db。这个类中没有其他方法,只有其他属性。
这是一个类,但是对于多个类的属性也有相同的用法,即使我们添加一个新的List属性并进行检查,它也可以正常工作。
- 这根本不应该奏效。通常-1的索引由InfexOf等方法返回,以返回特定实例的第一次出现。-1通常表示未找到该项目。除此之外,传递给List的-1索引将导致ArgumentException,因为索引不能小于零。
- 实施者或顾问是否有可能重写了方括号索引器?我猜他们使用的是将值应用于列表中的所有元素。但那真的很讨厌
- 我假设.Advisors不是.NET List的实例。它是一个特殊的实现,它重载了[index]操作符,如lordwilmore所说,并且-1处理了列表中的最后一个条目。
- 调试时,a.Advisors[-1]返回什么?我简直无法想象它竟然如此。
- 我认为EVK是对的,更多信息:stackoverflow.com/questions/11367902/negative-list-index
- 这是List真的System.Collections.Generic.List吗?
- 我开始认为我们应该解决这个问题,因为从目前发布的代码来看,如果没有例外的话,它是不可能运行代码的。必须有一些隐藏的东西,我们只能猜测,只要我们没有最小的、完整的和可验证的例子。
- @Himbrombere OP用代码更新了帖子。它确实坏了。
- 这是一个@muhammadahmad的列表,无法调试该行,只是跳过它
- @帕特里克霍夫曼,我都看到了,但从那以后,它是不可能成功运行。
- 事实上,除非这段代码从未被执行…@ HimBromBeere
- @gvk当你在Set行时,你用你的调试程序进入(f11)了吗?
- 没有任何异常,或者没有其他实现/重载。@Himbrombere,是的,F11
您使用的是预期的Expression的UpdateDefinitionBuilder.Set的过载。此表达式不是直接编译和执行的,而是转换为本机MongoDB语法,并用作MongoDB查询的一部分(与Entity Framework或其他ORM将表达式转换为SQL的方式相同)。这基本上是说"更新所有概述配置文件并设置第一个顾问的iscurrent标志,该标志与advisor.IsCurrent值匹配"。因为mongodb允许负索引(意思是相对于集合的结尾),所以c mongodb驱动程序可以将表达式转换为有效的mongodb查询(但请参见下面的更新)。
更新。如本文所述,-1对于MongoDB C驱动程序仍然有特殊意义。它将转换为位置更新运算符$:
the positional $ operator acts as a placeholder for the first element
that matches the query document
例如:
1 2 3 4
| var updateDefinition = new UpdateDefinitionBuilder <OverviewProfile >()
.Set(a => a .Advisors[-1].IsCurrent, false);
colleciton .UpdateOne(c => c .Advisors.Any(r => r .IsCurrent), updateDefinition ); |
将被转换为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| "updates": [{
"q": {
"Advisors": {
"$elemMatch": {
"IsCurrent": true
}
}
},
"u": {
"$set": {
"Advisors.$.IsCurrent": false // <- your expression
}
}
}
] |
但是,关于MongoDB中相对于收集结束的负索引含义的观点仍然成立,因为除-1(例如,-2)之外的任何其他负索引都将转换为如下查询:
1
| {"$set" : {"Advisors.-2.IsCurrent" : false} } |
- 从语句中创建的mongo表达式是什么?
- @Himbrombeere我更新了关于这个的更多信息。
如果a.Advisors确实是List的话,就没有用了。那会扔下一个江户。
更可能的是,这是在List上的一些自定义类或实现,其中传递给索引器的-1值意味着类似于"默认"值。
不管是什么,我认为这是一个糟糕的设计,应该避免。
- 只是为了添加一个官方参考…查看源代码
- "对List的实施"?列表的索引器不是虚拟的,您不能覆盖它(但是您可以隐藏它)。
- 类可以有一个自定义实现,索引器确实可以使用new隐藏。@ HimBromBeere
- @卡米洛特雷文托,我真不敢相信我没有想到那种不受约束的(uint)把戏。我不确定在BCL中看到它是恐怖还是有点好笑。