如何拥有C#只读功能但不限于构造函数?
C#“readonly”关键字是一个修饰符,当字段声明包含它时,对声明引入的字段的赋值只能作为声明的一部分或同一类的构造函数中发生。
现在假设我确实想要这个“赋值一次”约束,但我宁愿允许在构造函数之外完成赋值,可能是惰性/延迟评估/初始化。
我怎么能这么做呢?是否可以以一种很好的方式做到这一点,例如是否可以编写一些属性来描述这一点?
The C# "readonly" keyword is a modifier that when a field declaration includes it, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
Now suppose I do want this "assign value once" constraint, but I would rather allow the assignment be done outside of constructors, a lazy/late evaluation/initialization maybe.
How could I do that? and is it possible to do it in a nice way, for example, is it possible to write some attribute to describe this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果我正确理解你的问题,听起来你只想设置一个字段的值一次(第一次),并且不允许此后设置它。如果是这样,那么之前所有关于使用 Lazy(和相关)的帖子可能会有用。但如果您不想使用这些建议,也许您可以这样做:
If I understand your question correctly, it sounds like you just want to set a field's value once (the first time), and not allow it to be set after that. If that is so, then all the previous posts about using Lazy (and related) may be useful. But if you don't want to use those suggestions, perhaps you can do something like this:
请注意,延迟初始化很复杂,因此对于所有这些答案,如果您有多个线程,您应该小心尝试访问您的对象。
如果您想在类内部执行此操作,
您可以使用 C# 4.0 内置的延迟初始化功能:
或者对于旧版本的 C#,只需提供
get
方法,并检查您是否已使用支持字段进行初始化:如果您想在类之外执行此操作
您想要 Popsicle 不变性:
基本上:
Freeze
方法。ModifyFrozenObjectException
。IsFrozen
。顺便说一句,这些名字是我刚刚起的。诚然,我的选择很差,但目前还没有普遍遵循的惯例。
目前,我建议您创建一个
IReezable
接口以及可能的相关异常,这样您就不必依赖于 WPF 实现。像这样的东西:Note that lazy initialization is complicated, so for all of these answers you should be careful if you have multiple threads trying to access your object.
If you want to do this inside the class
You can use the C# 4.0 built-in lazy initialization features:
Or for older versions of C#, just supply a
get
method, and check if you're already initialized by using a backing field:If you want to do this outside the class
You want Popsicle Immutability:
Basically:
Freeze
method.ModifyFrozenObjectException
.IsFrozen
.BTW, I made up these names just now. My selections are admittedly poor, but there is no generically followed convention for this yet.
For now I'd recommend you create an
IFreezable
interface, and possibly related exceptions, so you don't have to depend on the WPF implementation. Something like:您可以使用
Lazy
class:GetFoo
仅在您第一次调用 Foo 属性时才会被调用。You can use the
Lazy<T>
class:GetFoo
will only be called the first time you call the Foo property.这在埃菲尔铁塔中被称为“一次”功能。这是 C# 中的一个重大疏忽。新的 Lazy 类型是一个很差的替代品,因为它不能与其非惰性版本互换,而是要求您通过其 Value 属性访问包含的值。因此,我很少使用它。噪声是 C# 代码的最大问题之一。理想情况下,人们想要这样的东西......
而不是当前的最佳实践......
This is know as the "once" feature in Eiffel. It is a major oversight in C#. The new Lazy type is a poor substitute since it is not interchangeable with its non-lazy version but instead requires you to access the contained value through its Value property. Consequently, I rarely use it. Noise is one of the biggest problems with C# code. Ideally, one wants something like this...
as oppose to the current best practice...