“常量正确性” 在 C# 中
const 正确性的要点是能够提供用户无法更改或删除的实例的视图。 编译器通过指出何时从 const 函数中破坏常量性或尝试使用 const 对象的非 const 函数来支持这一点。 那么,在不复制 const 方法的情况下,我是否可以在 C# 中使用具有相同目的的方法?
我知道不变性,但这并没有真正延续到容器对象,仅举一个例子。
The point of const-correctness is to be able to provide a view of an instance that can't be altered or deleted by the user. The compiler supports this by pointing out when you break constness from within a const function, or try to use a non-const function of a const object. So without copying the const approach, is there a methodology I can use in C# that has the same ends?
I'm aware of immutability, but that doesn't really carry over to container objects to name but one example.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我也多次遇到过这个问题,最终还是使用了接口。
我认为重要的是放弃 C# 是任何形式,甚至是 C++ 的演变的想法。 它们是两种不同的语言,但语法几乎相同。
我通常通过定义类的只读视图来表达 C# 中的“常量正确性”:
I've come across this issue a lot of times too and ended up using interfaces.
I think it's important to drop the idea that C# is any form, or even an evolution of C++. They're two different languages that share almost the same syntax.
I usually express 'const correctness' in C# by defining a read-only view of a class:
为了获得 const 疯狂(或函数式编程术语中的纯粹性)的好处,您需要以某种方式设计您的类,使它们不可变,就像 c# 的 String 类一样。
这种方法比仅仅将对象标记为只读要好得多,因为使用不可变类,您可以在多任务环境中轻松传递数据。
To get the benefit of const-craziness (or pureness in functional programming terms), you will need to design your classes in a way so they are immutable, just like the String class of c# is.
This approach is way better than just marking an object as readonly, since with immutable classes you can pass data around easily in multi-tasking environments.
我只是想向您指出,许多 System.Collections.Generics 容器都有一个 AsReadOnly 方法,它将返回一个不可变的集合。
I just wanted to note for you that many of the System.Collections.Generics containers have an AsReadOnly method which will give you back an immutable collection.
C#没有这样的功能。 您可以按值或按引用传递参数。 引用本身是不可变的,除非您指定 ref 修饰符。 但引用的数据并不是一成不变的。 所以如果你想避免副作用,你需要小心。
MSDN:
传递参数
C# doesn't have such feature. You can pass argument by value or by reference. Reference itself is immutable unless you specify ref modifier. But referenced data isn't immutable. So you need to be careful if you want to avoid side effects.
MSDN:
Passing Parameters
接口就是答案,实际上比 C++ 中的“const”更强大。 const 是解决“const”问题的一种通用解决方案,其中“const”被定义为“不设置成员或调用设置成员的内容”。 在许多情况下,这是常量性的一个很好的简写,但不是所有情况。 例如,考虑一个基于某些成员计算值但也缓存结果的函数。 在 C++ 中,这被认为是非常量,尽管从用户的角度来看它本质上是常量。
接口使您可以更加灵活地定义您想要从类中提供的特定功能子集。 想要常量吗? 只需提供一个没有变异方法的接口。 想要允许设置某些内容但不允许设置其他内容? 提供仅包含这些方法的接口。
Interfaces are the answer, and are actually more powerful than "const" in C++. const is a one-size-fits-all solution to the problem where "const" is defined as "doesn't set members or call something that sets members". That's a good shorthand for const-ness in many scenarios, but not all of them. For example, consider a function that calculates a value based on some members but also caches the results. In C++, that's considered non-const, although from the user's perspective it is essentially const.
Interfaces give you more flexibility in defining the specific subset of capabilities you want to provide from your class. Want const-ness? Just provide an interface with no mutating methods. Want to allow setting some things but not others? Provide an interface with just those methods.
同意其他一些观点,即使用在构造函数中初始化的只读字段来创建不可变对象。
或者,您也可以在属性上添加访问范围,即公共获取和受保护集?
Agree with some of the others look at using readonly fields that you initialize in the constructor, to create immutable objects.
Alternatively you could also add access scope on the properties, i.e. public get and protected set?
的问题>readonly是它只允许引用(指针)是常量。 所引用(指向)的事物仍然可以修改。 这是棘手的部分,但没有办法解决。 实现常量对象意味着使它们不公开任何可变的方法或属性,但这很尴尬。
另请参阅 有效的 C#:改进 C# 的 50 种具体方法(项目2 - 更喜欢只读而不是常量。)
The problem with readonly is that it only allows the reference (pointer) to be constant. The thing referenced (pointed to) can still be modified. This is the tricky part but there is no way around it. To implement constant objects means making them not expose any mutable methods or properties but this is awkward.
See also Effective C#: 50 Specific Ways to Improve Your C# (Item 2 - Prefer readonly to const.)