如何仅禁用索引器的setter?
我在工作中使用BannedApiAnalyzers来提升代码质量。我想阻止开发者这样做:
dictionary[key] = value;
当他们这样做时,我希望将其标记为一个警告,信息大致如下:
请勿使用索引器的设定器;请使用
Add()或扩展方法Replace()来明确表达你的意图。极少数情况下,如果你确实需要添加或替换,请使用扩展方法AddOrReplace()。
如何在BannedSymbols.txt中设置这条规则?
以下是我尝试过的:
尝试#1:
P:System.Collections.Generic.Dictionary`2.Item(`0)
这在某种意义上是可行的,因为该符号确实被禁止了,但它导致索引器的getter和 setter都被禁止了,这不是我想要的:开发者当然必须能够继续使用getter;只有setter必须被禁止。
尝试#2:
M:System.Collections.Generic.Dictionary`2.set_Item(`0,`1)
这不起作用;它什么也没做;它导致静默失败,这似乎是BannedApiAnalyzers的默认工作模式。
有没有仅禁止setter的方法?怎么做?
解决方案
看起来目前通过Banned API Analyzers无法单独定位属性/索引器的setter/getter。该库是在所谓的“ID字符串格式”之上运行的(文档):
要将符号添加到禁止列表,只需将以下格式的条目添加到任一配置文件中(诊断中的描述文本将显示为描述,这是可选的):
none {Documentation Comment ID string for the symbol}[;Description Text]有关ID字符串格式的详细信息,请参阅 "ID string format"。
目前这仅处理属性/索引器名称:
属性和索引器
cs namespace Acme { class Widget : IProcess { public int Width { get { ... } set { ... } } public int this[int i] { get { ... } set { ... } } public int this[string s, int i] { get { ... } set { ... } } } }"P:Acme.Widget.Width" "P:Acme.Widget.Item(System.Int32)" "P:Acme.Widget.Item(System.String,System.Int32)"
因此你要么推出你自己的分析器(dictionary[key] = value; 是一个 SimpleAssignmentExpression/AssignmentExpression,目标为 PropertyReference,实现起来应该相对容易,我也尝试过通过[DocumentationCommentId]来生成ID字符串),要么彻底禁用标准字典并自行实现一个带get-only索引器的版本。