2016-08-24 30 views
5

我正在寻找一个错误提升来防止构建,如果我的静态字典中有重复的键。编译器检查字典中的键是否唯一

我下面

public static readonly Dictionary<string, string> Fruits = new Dictionary<string, string> 
{ 
    {"Sobeys", "Apples"}, 
    {"NoFrills", "Oranges"} 
} 

但可以说,有人不小心改变索贝斯是Nofrills,我想一个编译器错误当前字典待提高,以防止任何东西要做,直到重复键解决。请问可能吗?如果是这样,我会怎么做?

public static readonly Dictionary<string, string> Fruits = new Dictionary<string, string> 
{ 
    {"NoFrills", "Apples"}, 
    {"NoFrills", "Oranges"} 
} 
+4

你必须,如果你希望它有比C#的规则,不同的行为写自己的编译器。 – Servy

+3

您使用的是Visual Studio 2015或更新版本?如果是这样,可以使用自定义[实时代码分析器](https://msdn.microsoft.com/en-us/magazine/dn879356.aspx),但它将成为一项非繁杂的工作量强大的。 –

+0

@Servy因为C#是开源的,所以也许应该向社区提交补丁。 https://github.com/dotnet/roslyn –

回答

6

你也可以使用下面的黑客(我不推荐它):将匿名类型转换为字典。 匿名类型不允许重复的属性名称。

例子:

Dictionary<string, string> Fruits = ToDictionary(
    new 
    { 
     Sobeys = "Apples", 
     NoFrills = "Oranges" 
    } 
); 

但这种方法有以下限制:只能有有效的标识符在你的字典键。

如何实现ToDictionary方法有描述: In c# convert anonymous type into key/value array?

+0

有趣的,我会给这个快速尝试! – Master

+2

这是一个非常聪明的想法。 – sstan

+0

嗨,绝对是黑客,但这基本上是我想要的。谢谢@ just.ru – Master

8

不,这是一个运行时间的事情。一旦这个类被加载到内存中,它将抛出一个异常(这本质上是运行时)。

您可以通过诊断分析器添加自定义检查,但这对获得非常小的收益会很痛苦。我建议你保持原样,并密切关注新部署的例外情况。您可以随时添加评论,以便向其他开发者明确说明密钥必须是唯一的,但是您在哪里停止?开发人员应该知道这样的基本框架规则。

例如,您也可以使用枚举作为密钥,当您尝试添加已存在的内容时,它会在devtime中将其清除。另一种选择是参考const string字段,尽管它仍然有些脆弱。

+1

我几乎想和你说一样的东西,但是我唯一要补充的是这个单元测试能很好地抓住 –

+0

@ScottChamberlain单元测试对于通过方法完成添加是有帮助的,但是您在初始化课程 –

+0

@JeroenVannevel时是否已经重复进行单元测试?访问该属性将失败,并出现异常 - 所以使用它的测试将失败......不知道为什么你会写出测试成功,当抛出异常... –

1

C#编译器不提供这种可能性。 您将在运行时得到一个异常。

要解决这个问题,您必须实现自己的预处理检查或处理运行时异常。

1

我想一个编译器错误,以提高

这是错误。这就是编译器不会发出编译时错误的原因。集合初始化器是语法糖,并被翻译成各自的Add()方法(或者在替代语法的情况下为索引器)调用。

您最好的选择是依靠一些第三方代码分析工具,可以发现潜在的错误。

相关问题