c# - 具有丰富类型的 C# 中的 Const 正确性

标签 c# .net constants const-correctness readonly

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

因此,我一直在尝试确定一种模式,我可以使用它来在 C# 中实现 const 正确性。

This answer有一个有趣的建议:为所有类型创建一个只读界面。但正如 Matt Cruikshank 在评论中指出的那样,如果您的类(class)有集合或其他丰富的类型,这就会成为问题。特别是如果您无法控制类型,并且无法使其实现只读接口(interface)。

是否存在任何可以处理丰富类型和集合的模式或解决方案,或者我们是否被迫在 C# 中简单地制作副本?完全放弃 C# 中的 const 正确性是否更好?

最佳答案

你能在 C# 中获得不可变性吗?当然,如果您为此设计。你可以用接口(interface)做一些有创意的事情,等等,只暴露get。属性和可变方法都没有。

也就是说,请记住,没有什么可以阻止狡猾的用户将其转换回实际类型(当然,对于 C++ 也可以这样说,您可以抛弃 const-ness)。

ISomeReadOnlyInterface readOnly = new SomeFullObject();

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

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

所以恐怕这里真的没有简单的答案。没有“翻转开关”const 可以为您提供 C++ 的功能。

这完全取决于您,您可以:

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

后者就是收藏之类的Dictionary<TKey, TValue>做。没有什么说你不能使 key 类型成为可变类型(但如果你这样做了),MSDN 非常清楚,如果你以哈希码更改的方式更改 key ,它就在你自己的脖子上...

对于我自己的工作,我倾向于保持简单,除非真的很担心我的类可能会以导致副作用的方式被改变。例如,如果我将 Web 服务结果存储在缓存中,我将返回缓存项的副本,这样如果用户修改结果,他们就不会无意中修改缓存值。

总而言之,我不会担心您返回的每种类型的常量正确性,这太过分了。我只担心你退回的东西,如果改变了,可能会对其他用户产生副作用。

关于c# - 具有丰富类型的 C# 中的 Const 正确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11639365/

相关文章:

.net - GZip 压缩(通过 .net)会增加文件大小吗?

c# - 另一个 System.Runtime.InteropServices 错误

Java: `enum` 与 `String` 作为参数

用于存储常量的 Android 嵌套接口(interface)

c# - 日期时间字符串解析

c# - 未调用 EF 4.1 OnModelCreating

c# - 添加引用对话框中的程序集是否因使用的 .Net 框架而异?

c++ - const change without const_cast<> 为什么没有编译器警告/错误?

c# - 如何访问另一个类中的属性?

c# - 将 xmlns 属性添加到根元素