具有丰富类型的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,这太过分了。 我只担心你返回的东西,如果改变了,可能会给其他用户带来副作用。