具有丰富类型的C#中的const正确性

来自C ++背景并尝试学习C#,我遇到的最令人沮丧的语言遗漏之一是与const关键字等效。

所以,我一直试图找到一种模式,我可以用它来实现C#中的const正确性。

这个答案有一个有趣的建议:为你的所有类型创建一个只读界面。 但正如Matt Cruikshank在评论中指出的那样,如果你的class级有collections品或其他丰富的类型,这就成了问题。 特别是如果您无法控制类型,并且无法使其实现只读接口。

是否存在可以处理丰富类型和集合的任何模式或解决方案,或者我们是否强制在C#中进行复制? 在C#中完全放弃const正确性是否更好?

你能在C#中获得不变性吗? 当然,如果你为它设计。 您可以使用接口创建创造性的东西,等等,只显示属性的get ,而不显示任何可变方法。

也就是说,请记住,没有任何东西可以阻止狡猾的用户将其转换回实际类型(当然,C ++也可以说,你可以抛弃常量)。

 ISomeReadOnlyInterface readOnly = new SomeFullObject(); // hah, take that read-only interface! ((SomeFullObject)readOnly).SomeMutatingMethod(); 

与集合相同。 即使你返回一个ReadOnlyCollection(它可以防止对集合本身的变异行为),集合中的数据仍然是可变的(只要类型允许它当然)。

所以我担心这里真的没有简单的答案。 没有“flip-a-switch”const可以为你提供C ++的function。

这取决于你,你可以:

  • 将您的类型设计为不可变的并返回迭代器(或其他只读序列)而不是可变集合。
  • 每次都要返回新的副本,这样如果他们改变它们就没什么大不了的。
  • 只需返回实际数据并将篡改行为保留为“未定义”。
  • 等等…

后者是像Dictionary这样的集合。 没有什么可以说你不能把密钥类型变成一个可变类型(但如果你这样做会有祸害),并且MSDN非常清楚,如果你以改变哈希代码的方式改变密钥,它就在你自己的脖子上…

对于我自己的工作,我倾向于保持简单,除非实际上有一个很大的问题,我的课程可能会以一种会导致副作用的方式被改变。 例如,如果我将Web服务结果存储在缓存中,我将返回缓存项的副本,以便在用户修改结果时不会无意中修改缓存的值。

所以,很长一段时间,我不会担心你返回的每种类型的const-correctness,这太过分了。 我只担心你返回的东西,如果改变了,可能会给其他用户带来副作用。