Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

c# - How can I make a read only version of a class?

I have a class with various public properties which I allow users to edit through a property grid. For persistence this class is also serialized/deserialized to/from an XML file through DataContractSerializer.

Sometimes I want to user to be able to save (serialize) changes they've made to an instance of the class. Yet at other times I don't want to allow the user to save their changes, and should instead see all the properties in the property grid as read only. I don't want to allow users to make changes that they'll never be able to save later. Similar to how MS Word will allow users to open documents that are currently opened by someone else but only as read only.

My class has a boolean property that determines if the class should be read-only, but is it possible to use this property to somehow dynamically add a read-only attributes to the class properties at run-time? If not what is an alternative solution? Should I wrap my class in a read-only wrapper class?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Immutability is an area where C# still has room to improve. While creating simple immutable types with readonly properties is possible, once you need more sophisticated control over when type are mutable you start running into obstacles.

There are three choices that you have, depending on how strongly you need to "enforce" read-only behavior:

  1. Use a read-only flag in your type (like you're doing) and let the caller be responsible for not attempting to change properties on the type - if a write attempt is made, throw an exception.

  2. Create a read-only interface and have your type implement it. This way you can pass the type via that interface to code that should only perform reads.

  3. Create a wrapper class that aggregates your type and only exposes read operations.

The first option is often the easiest, in that it can require less refactoring of existing code, but offers the least opportunity for the author of a type to inform consumers when an instance is immutable vs when it is not. This option also offers the least support from the compiler in detecting inappropriate use - and relegates error detection to runtime.

The second option is convenient, since implementing an interface is possible without much refactoring effort. Unfortunately, callers can still cast to the underlying type and attempt to write against it. Often, this option is combined with a read-only flag to ensure the immutability is not violated.

The third option is the strongest, as far as enforcement goes, but it can result in duplication of code and is more of a refactoring effort. Often, it's useful to combine option 2 and 3, to make the relationship between the read-only wrapper and the mutable type polymorphic.

Personally, I tend to perfer the third option when writing new code where I expect to need to enforce immutability. I like the fact that it's impossible to "cast-away" the immutable wrapper, and it often allows you to avoid writing messy if-read-only-throw-exception checks into every setter.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...