Now suppose I do want this "assign value once" constraint, but I would rather allow the assignment be done outside of constructors
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:
public string SomeValue
{
get
{
// Note: Not thread safe...
if(someValue == null)
{
someValue = InitializeSomeValue(); // Todo: Implement
}
return someValue;
}
}
If you want to do this outside the class
You want Popsicle Immutability:
Basically:
- You make the whole class writable, but add a
Freeze
method.
- Once this freeze method is called, if users try to call setters or mutator methods on your class, you throw a
ModifyFrozenObjectException
.
- You probably want a way for external classes to determine if your class
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:
public interface IFreezable
{
void Freeze();
bool IsFrozen { get; }
}
LazyInitializer
class, perhaps? msdn.microsoft.com/en-us/library/…. There's alsoLazy<T>
. See msdn.microsoft.com/en-us/library/dd997286.aspx. – Mockingbird