What is a "mostly complete" (im)mutability approach for C#? [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Since immutability is not fully baked into C# to the degree it is for F#, or fully into the framework (BCL) despite some support in the CLR, what's a fairly complete solution for (im)mutability for C#?
My order of preference is a solution consisting of general patterns/principles compatible with
a single open-source library with few dependencies
a small number of complementary/compatible open-source libraries
something commercial
that
covers Lippert's kinds of immutability
offers decent performance (that's vague I know)
supports serialization
supports cloning/copying (deep/shallow/partial?)
feels natural in scenarios such as DDD, builder patterns, configuration, and threading
provides immutable collections
I'd also like to include patterns you as the community might come up with that don't exactly fit in a framework such as expressing mutability intent through interfaces (where both clients that shouldn't change something and may want to change something can only do so through interfaces, and not the backing class (yes, I know this isn't true immutability, but sufficient):
public interface IX
{
int Y{ get; }
ReadOnlyCollection<string> Z { get; }
IMutableX Clone();
}
public interface IMutableX: IX
{
new int Y{ get; set; }
new ICollection<string> Z{ get; } // or IList<string>
}
// generally no one should get ahold of an X directly
internal class X: IMutableX
{
public int Y{ get; set; }
ICollection<string> IMutableX.Z { get { return z; } }
public ReadOnlyCollection<string> Z
{
get { return new ReadOnlyCollection<string>(z); }
}
public IMutableX Clone()
{
var c = MemberwiseClone();
c.z = new List<string>(z);
return c;
}
private IList<string> z = new List<string>();
}
// ...
public void ContriveExample(IX x)
{
if (x.Y != 3 || x.Z.Count < 10) return;
var c= x.Clone();
c.Y++;
c.Z.Clear();
c.Z.Add("Bye, off to another thread");
// ...
}

Would the better solution be to just use F# where you want true immutability?

Use this T4 template I put together to solve this problem. It should generally suit your needs for whatever kinds of immutable objects you need to create.
There's no need to go with generics or use any interfaces. For my purposes, I do not want my immutable classes to be convertible to one another. Why would you? What common traits should they share that means they should be convertible to one another? Enforcing a code pattern should be the job of a code generator (or better yet, a nice-enough type system to allow you to do define general code patterns, which C# unfortunately does not have).
Here's some example output from the template to illustrate the basic concept at play (nevermind the types used for the properties):
public sealed partial class CommitPartial
{
public CommitID ID { get; private set; }
public TreeID TreeID { get; private set; }
public string Committer { get; private set; }
public DateTimeOffset DateCommitted { get; private set; }
public string Message { get; private set; }
public CommitPartial(Builder b)
{
this.ID = b.ID;
this.TreeID = b.TreeID;
this.Committer = b.Committer;
this.DateCommitted = b.DateCommitted;
this.Message = b.Message;
}
public sealed class Builder
{
public CommitID ID { get; set; }
public TreeID TreeID { get; set; }
public string Committer { get; set; }
public DateTimeOffset DateCommitted { get; set; }
public string Message { get; set; }
public Builder() { }
public Builder(CommitPartial imm)
{
this.ID = imm.ID;
this.TreeID = imm.TreeID;
this.Committer = imm.Committer;
this.DateCommitted = imm.DateCommitted;
this.Message = imm.Message;
}
public Builder(
CommitID pID
,TreeID pTreeID
,string pCommitter
,DateTimeOffset pDateCommitted
,string pMessage
)
{
this.ID = pID;
this.TreeID = pTreeID;
this.Committer = pCommitter;
this.DateCommitted = pDateCommitted;
this.Message = pMessage;
}
}
public static implicit operator CommitPartial(Builder b)
{
return new CommitPartial(b);
}
}
The basic pattern is to have an immutable class with a nested mutable Builder class that is used to construct instances of the immutable class in a mutable way. The only way to set the immutable class's properties is to construct a ImmutableType.Builder class and set that in the normal mutable way and convert that to its containing ImmutableType class with an implicit conversion operator.
You can extend the T4 template to add a default public ctor to the ImmutableType class itself so you can avoid a double allocation if you can set all the properties up-front.
Here's an example usage:
CommitPartial cp = new CommitPartial.Builder() { Message = "Hello", OtherFields = value, ... };
or...
CommitPartial.Builder cpb = new CommitPartial.Builder();
cpb.Message = "Hello";
...
// using the implicit conversion operator:
CommitPartial cp = cpb;
// alternatively, using an explicit cast to invoke the conversion operator:
CommitPartial cp = (CommitPartial)cpb;
Note that the implicit conversion operator from CommitPartial.Builder to CommitPartial is used in the assignment. That's the part that "freezes" the mutable CommitPartial.Builder by constructing a new immutable CommitPartial instance out of it with normal copy semantics.

Personally, I'm not really aware of any third party or previous solutions to this problem, so my apologies if I'm covering old ground. But, if I were going to implement some kind of immutability standard for a project I was working on, I would start with something like this:
public interface ISnaphot<T>
{
T TakeSnapshot();
}
public class Immutable<T> where T : ISnaphot<T>
{
private readonly T _item;
public T Copy { get { return _item.TakeSnapshot(); } }
public Immutable(T item)
{
_item = item.TakeSnapshot();
}
}
This interface would be implemented something like:
public class Customer : ISnaphot<Customer>
{
public string Name { get; set; }
private List<string> _creditCardNumbers = new List<string>();
public List<string> CreditCardNumbers { get { return _creditCardNumbers; } set { _creditCardNumbers = value; } }
public Customer TakeSnapshot()
{
return new Customer() { Name = this.Name, CreditCardNumbers = new List<string>(this.CreditCardNumbers) };
}
}
And client code would be something like:
public void Example()
{
var myCustomer = new Customer() { Name = "Erik";}
var myImmutableCustomer = new Immutable<Customer>(myCustomer);
myCustomer.Name = null;
myCustomer.CreditCardNumbers = null;
//These guys do not throw exceptions
Console.WriteLine(myImmutableCustomer.Copy.Name.Length);
Console.WriteLine("Credit card count: " + myImmutableCustomer.Copy.CreditCardNumbers.Count);
}
The glaring deficiency is that the implementation is only as good as the client of ISnapshot's implementation of TakeSnapshot, but at least it would standardize things and you'd know where to go searching if you had issues related to questionable mutability. The burden would also be on potential implementors to recognize whether or not they could provide snapshot immutability and not implement the interface, if not (i.e. the class returns a reference to a field that does not support any kind of clone/copy and thus cannot be snapshot-ed).
As I said, this is a start—how I'd probably start—certainly not an optimal solution or a finished, polished idea. From here, I'd see how my usage evolved and modify this approach accordingly. But, at least here I'd know that I could define how to make something immutable and write unit tests to assure myself that it was.
I realize that this isn't far removed from just implementing an object copy, but it standardizes copy vis a vis immutability. In a code base, you might see some implementors of ICloneable, some copy constructors, and some explicit copy methods, perhaps even in the same class. Defining something like this tells you that the intention is specifically related to immutability—I want a snapshot as opposed to a duplicate object because I happen to want n more of that object. The Immtuable<T> class also centralizes the relationship between immutability and copies; if you later want to optimize somehow, like caching the snapshot until dirty, you needn't do it in all implementors of copying logic.

If the goal is to have objects which behave as unshared mutable objects, but which can be shared when doing so would improve efficiency, I would suggest having a private, mutable "fundamental data" type. Although anyone holding a reference to objects of this type would be able to mutate it, no such references would ever escape the assembly. All outside manipulations to the data must be done through wrapper objects, each of which holds two references:
UnsharedVersion--Holds the only reference in existence to its internal data object, and is free to modify it
SharedImmutableVersion--Holds a reference to the data object, to which no references exist except in other SharedImmutableVersion fields; such objects may be of a mutable type, but will in practice be immutable because no references will ever be made available to code that would mutate them.
One or both fields may be populated; when both are populated, they should refer to instances with identical data.
If an attempt is made to mutate an object via the wrapper and the UnsharedVersion field is null, a clone of the object in SharedImmutableVersion should be stored in UnsharedVersion. Next, SharedImmutableCVersion should be cleared and the object in UnsharedVersion mutated as desired.
If an attempt is made to clone an object, and SharedImmutableVersion is empty, a clone of the object in UnsharedVersion should be stored into SharedImmutableVersion. Next, a new wrapper should be constructed with its UnsharedVersion field empty and its SharedImmutableVersion field populated with the SharedImmutableVersion from the original.
It multiple clones are made of an object, whether directly or indirectly, and the object hasn't been mutated between the construction of those clones, all clones will refer to the same object instance. Any of those clones may be mutated, however, without affecting the others. Any such mutation would generate a new instance and store it in UnsharedVersion.

Related

Check if object is defined after initialization in c#

I have the following object (class).
namespace Temp.Models
{
public class CurrentClass
{
private double _firstCoefficient;
private double _secondCoefficient;
public double FirstCoefficient
{
get { return _firstCoefficient; }
set { _firstCoefficient= value; }
}
public double SecondCoefficient
{
get { return _secondCoefficient; }
set { _secondCoefficient= value; }
}
}
}
The following class utilizes the above object and therefore initializes the object as follows:
namespace Temp.Models
{
public class MainClass
{
private CurrentClass _currentClass = new CurrentClass();
public CurrentClass CurrentClass
{
get { return _currentClass; }
set { _currentClass = value; }
}
}
}
At some point if certain conditions are met I would define the variables as follows:
MainClass currentObject = new MainClass();
//if conditions are met
currentObject.CurrentClass.FirstCoefficient = 0;
currentObject.CurrentClass.SecondCoefficient = 5;
But what if the conditions are never met and I never define the above variables. How and/or what is the best way to check if the object was never defined?
I can do the following check:
if(currentObject.CurrentClass.FirstCoefficient != 0 && currentObject.CurrentClass.SecondCoefficent != 0)
But the values can be defined as 0...So I am not sure how to go about this.
Any help is much appreciated!
These are some principles that can be used for solving the problem with description, samples and brief evaluation/opinion.
1. Parametrization through constructors
According to OOP principles, a constructor is method used to initialize an object to a valid state. The concept of immutability takes this even further, disallowing any changes, completely avoiding invalid state.
There is also a possibility of compromise where the API of an object disallows invalid states.
With this concept, you would arrive to:
namespace Temp.Models
{
public class CurrentClass
{
public double FirstCoefficient { get; private set; }
public double SecondCoefficient { get; private set; }
public CurrentClass(double firstCoefficient, double secondCoefficient)
{
FirstCoefficient = firstCoefficient;
SecondCoefficient = secondCoefficient;
}
// if mutability is required - this is needless as the constructor is
// the same but if there was more complex state, methods like this would make
// sense, mutating only parts of the state
public void SetCoefficients(double firstCoefficient, double secondCoefficient)
{
FirstCoefficient = firstCoefficient;
SecondCoefficient = secondCoefficient;
}
}
}
Summary:
Each instantiation of CurrentClass is always in a valid state, avoiding a lot of consistency checks (improved encapsulation)
It takes more code to write (but you save a lot of other code due to the previous point)
You need to know the coefficients beforehand.
2. Using nullable types
Nullable types add the "additional" value to types, the "undefined" state. Reference types (class) are nullable by design while value types (struct) need to be marked nullable, either as Nullable<T> or with the shorthand T?.
This then allows the objects be in invalid state and be specific about it. This goes to the other end of consistency scale from immutability as an object with multiple nullable fields has many invalid states.
Sample code:
namespace Temp.Models
{
public class CurrentClass
{
public double? FirstCoefficient { get; set; }
public double? SecondCoefficient { get; set; }
}
}
Now this gets instantiated quite nicely and can be changed on the fly:
public CurrentClass CreateCurrentClass()
{
var currentClass = new CurrentClass { FirstCoefficient = 1.0 };
var secondCoefficient = RetrieveSecondCoefficient();
currentClass.SecondCoefficient = secondCoefficient;
return currentClass;
}
You'll however need validity checks everywhere the object is used.
public bool IsValid(CurrentClass currentClass)
{
// what if FirstCoefficient has value and SecondCoefficient doesn't,
// is that always an invalid state?
return currentClass.FirstCoefficient.HasValue
&& currentClass.SecondCoefficient.HasValue;
}
Summary:
Very little code is needed to have a DTO up and running
A lot of consistency checks (and related brain pain) are required to work with such model
Encapsulation is lacking - any method taking CurrentClass can alter its validity, therefore making the previous point even worse. This can be eased by usage of read-only interface passed where read-only access is required.
Summing up
There are many other means that usually lay in between the two aforementioned approaches. For example you can use one validity flag (SergeyS's response) per object and ease on the external validity checks but having more code in the class and the need of deeper thinking.
Personally, I prefer immutability. It's more monkey code to write but will definitely pay off down the road thanks to the clean design.
A complex system without immutability is very hard to reason about without extensive knowledge. This is especially painful when working in a team - usually each person only knows a part of the codebase.
The sad thing is that it's not always possible to have evertything immutable (e.g. viewmodels): then I tend to convert objects to an internal immutable model as soon as it's possible.
Given what you already wrote, I would add Initialize() method and Initialized property into your MainClass class. Something similar to this:
public class MainClass
{
private CurrentClass _currentClass = new CurrentClass();
public CurrentClass CurrentClass
{
get { return _currentClass; }
set { _currentClass = value; }
}
public bool Initialized {get; private set;}
public void Initialize()
{
this.CurrentClass.FirstCoefficient = 0;
this.CurrentClass.SecondCoefficient = 5;
this.Initialized = true;
}
}
Call Initialize() method where your conditions met.
Later in code you can just check if(currentObject.Initialized). Notice private setter for `Initialized' property, it will ensure this flag was not accidentally set by external code.
Depending on your needs, you can go further and pass parameters for initialization directly to Initialize() method as parameters.
You have several approaches, like force values to be correct in constructor or have another variable telling if object has no value yet, like System.Drawing.Point has static "Empty" property. But in this case of your simple object your main class is explicitly creating an instance of CurrentClass so at this point this object should be correct and coefficients should be set. If you rely on some other code to set those values to perform some other action later, it is out of scope of these two objects here.
Update: perharps sharing details of what the real problem is would be better, because I have a feeling trying to provide a simpified example ended up in hiding real problem.

Maintaining open and readonly versions of the same class

Lately I have come across quite a few scenarios where an open and a read only version of a class is required. A common scenario is a settings class that users can set properties for but when the settings have been validated and going through a long-running operation, they should only have access to a read-only version.
These classes are not a generic store and are strongly typed.
Currently I just inherit from a read/write version and throw exceptions on write attempts and was wondering if there is a more streamlined way people do this.
First, note that there is a difference between "read-only" and "immutable". Let's say you giving r ("receiver") a reference to your object o ("object"):
If you just want to be sure that r won't change the value of o, then an interface-based solution like this one should suffice and is probably as easy as it will get.
var o = new List<int> { 1, 2, 3 };
r.LookAtList((IEnumerable<int>)o);
r.LookAtList will see o as a read-only sequence because the IEnumerable<> abstraction is read-only.
If you also want to ensure that r will always observe the same value for o, then that interface-based solution won't be enough. Consider this:
var o = new List<int> { 1, 2, 3 };
r.LookAtList((IEnumerable<int>)o);
o.Add(4);
r.LookAtList((IEnumerable<int>)o);
While r.LookAtList won't be able to change the original object o (unless it uses reflection or casts the IEnumerable<> back to a List<>), it will observe a different sequence the second time around, even though it is passed exactly the same IEnumerable<> reference.
If you truly want a read-write version of some type and an immutable version, then you will end up with two distinct types. I suggest that you consider the Builder pattern:
sealed class FooBuilder
{
public TA A { get; set; }
public TB B { get; set; }
…
public Foo Build() { return new Foo(A, B, …); }
}
sealed class Foo
{
public Foo(TA a, TB b, …)
{
… // validate arguments
this.a = a;
this.b = b;
…
}
private readonly TA a;
private readonly TB b;
…
public TA A { get { return a; } }
public TB B { get { return b; } }
…
}
But that is quite verbose and you probably hoped to get around all that duplication. Unfortunately, implementing truly immutable types requires a lot of verbosity in the current version of the C# programming language.
This might change somewhat in the upcoming version (6) of C#.
Why not use an interface? Pass the object as the interface where you want it to be read only but pass it as a concrete type where you want it to be read-writable.
public interface IUserSettings
{
int Value1 { get; }
string Value2 { get; }
}
public class UserSettings : IUserSettings
{
public int Value1 { get; set; }
public string Value2 { get; set; }
}
You could also then update your UI to display UserSettings and IUserSettings differently (i.e. have 1 template show edit controls and 1 template show read only controls.)
My first notion would be to have a struct FooDefaults with properties for the default values, and pass that into the constructor for Foo (your property class), which uses the defaults (after validation) to initialize members returned from readonly properties.
The pattern used by Microsoft's own Freezable hierarchy in WPF does exactly what you describe. See for instance Freezable.WritePreamble:
if (IsFrozenInternal)
{
throw new InvalidOperationException(
SR.Get(SRID.Freezable_CantBeFrozen,GetType().FullName));
}
Freezable uses 'IsFrozen` for clients to figure out whether an object is immutable or not.
why not just shut down the set?
private string prop1 = string.Empty;
public string Prop1
{
get { return prop1; }
set
{
if (ValueIsValid(prop1))
{
NotifyPropertyChanged("Prop1");
return; // or you can throw an exeption
}
if (prop1 == value) return;
prop1 = value;
NotifyPropertyChanged("Prop1");
}
}

How to pass data between function calls

We can pass data between functions by using class objects. Like i have class
public class AddsBean
{
public long addId{get;set;}
public int bid { get; set; }
public long pointsAlloted { get; set; }
public string userId { get; set; }
public enum isApproved { YES, NO };
public DateTime approveDate { get; set; }
public string title { get; set; }
public string description { get; set; }
public string Link { get; set; }
public DateTime dateAdded { get; set; }
}
We can call function like public List<AddsBean> getAdds(string Id). This approach is good when you need all the variables of class. But what if you need only 2 or 3 variables of class?
Passing object of class is not good because it will be wastage of memory. Another possible solution is to make different classes of lesser variables but that is not practical.
What should we do that will best possible solution to fulfill motive and best according to performance also?
In Java - "References to objects are passed by value".. So, you dont pass the entire object, you just pass the reference to the object to the called function.
EG:
class A{
int i;
int j;
double k;
}
class B{
public static void someFunc(A a) // here 'a' is a reference to an object, we dont pass the object.
{
// some code
}
public static void main(String[] args){
A a = new A();
B.someFunc(a); // reference is being passed by value
}
}
first of all, as Java is pass by value and references typed, there is no need to worry about the memory wastage.
next, as you have mentioned, it is not good to pass all the object if you do not need them all, in some situation, it's true. as you need to protect your data in instance, thus you can use different granularity of class, for instance:
class A
{id, name}
class B extends A
{password,birthday}
by refer to different class you can control the granularity yourself, and provide different client with different scope of data.
But in some condition, you need to use a instance to store all data in the whole application, like configure data in hadoop, or some other configuration related instance.
Try to choose the most suitable scope!
If you're sure that this is the source of problems and you don't want to define a new class with a subset of the properties, .NET provides the Tuple class for grouping a small number of related fields. For example, a Tuple<int, int, string> contains two integers and a string, in that order.
public Tuple<string, long, DateTime> GetPointsData()
{
AddsBean bean = ... // Get your AddsBean somehow
return Tuple.Create<string, long, DateTime>(bean.userId, bean.pointsAlloted, bean.approveDate);
}
Once this method goes out of scope, there is no longer a live reference to the object bean referred to and will be collected by the garbage collector at some point in the future.
That said, unless you're sure that instances of the AddsBean class are having a noticeable negative effect on the performance of your app, you should not worry about it. The performance of your application is probably affected far more by other operations. Returning a reference type (a type defined with class instead of struct) only passes a reference to the object, not the data of the object itself.

Design pattern for returning a data structure object that might not always be fully populated?

I have a situation where I am querying a RESTful web-service (using .NET) that returns data as XML. I have written wrapper functions around the API so that instead of returning raw XML I return full .NET objects that mirror the structure of the XML. The XML can be quite complicated so these objects can be pretty large and heavily nested (ie. contain collections that in turn may house other collections etc.).
The REST API has an option to return a full result or a basic result. The basic result returns a small subset of the data that the full result does. Currently I am dealing with the two types of response by returning the same .NET object for both types of request - but in the basic request some of the properties are not populated. This is best shown by a (very oversimplified) example of the code:
public class PersonResponse
{
public string Name { get; set; }
public string Age { get; set; }
public IList<HistoryDetails> LifeHistory { get; set; }
}
public class PersonRequest
{
public PersonResponse GetBasicResponse()
{
return new PersonResponse()
{
Name = "John Doe",
Age = "50",
LifeHistory = null
};
}
public PersonResponse GetFullResponse()
{
return new PersonResponse()
{
Name = "John Doe",
Age = "50",
LifeHistory = PopulateHistoryUsingExpensiveXmlParsing()
};
}
}
As you can see the PersonRequest class has two methods that both return a PersonResponse object. However the GetBasicResponse method is a "lite" version - it doesn't populate all the properties (in the example it doesn't populate the LifeHistory collection as this is an 'expensive' operation). Note this is a very simplified version of what actually happens.
However, to me this has a definite smell to it (since the caller of the GetBasicResponse method needs to understand which properties will not be populated).
I was thinking a more OOP methodology would be to have two PersonResponse objects - a BasicPersonResponse object and a FullPersonResponse with the latter inheriting from the former. Something like:
public class BasicPersonResponse
{
public string Name { get; set; }
public string Age { get; set; }
}
public class FullPersonResponse : BasicPersonResponse
{
public IList<object> LifeHistory { get; set; }
}
public class PersonRequest
{
public BasicPersonResponse GetBasicResponse()
{
return new FullPersonResponse()
{
// ...
};
}
public FullPersonResponse GetFullResponse()
{
return new FullPersonResponse()
{
// ...
};
}
}
However, this still doesn't quite "feel" right - for reasons I'm not entirely sure of!
Is there a better design pattern to deal with this situation? I feel like I'm missing something more elegant? Thanks!
I my opinion you have describe a proxy pattern. See details here: Illustrated GOF Design Patterns in C#
I also have a nagging bad feeling about using inheritance to add on 'extra data', rather than adding/modifying behavior. The main advantage of this is that your methods can specify which level of detail they require in their argument types.
In this particular example, I would be inclined to use the first approach for the data transfer object (the Response object), but then immediately consume this data transfer object to create data model objects, the exact nature of which depends heavily on your specific application. The data transfer object should be internal (as the presence or absence of the data field is an implementation detail) and the public objects or interfaces should provide a view that's more suitable to the consuming code.

Locking an object to prevent any data changes

Bit of an odd one this...
Lets say I have the following class:
public class Wibble
{
public string Foo {get;set;}
public string Bar {get;set;}
}
This class is used a process where the values of Foo and Bar are updated/changed. However after a certain point in the process I want to "lock" the instance to prevent any changes from being made. So the question is how best to do this?
A solution of sorts would be something like this:
public class Wibble
{
private string _foo;
private string _bar;
public bool Locked {get; set;}
public string Foo
{
get
{
return this._foo
}
set
{
if (this.Locked)
{
throw new ObjectIsLockedException()
}
this._foo = value;
}
}
public string Bar
{
get
{
return this._bar
}
set
{
if (this.Locked)
{
throw new ObjectIsLockedException()
}
this._bar = value;
}
}
}
However this seems a little inelegant.
The reason for wanting to do this is that I have an application framework that uses externally developed plugins that use the class. The Wibble class is passed into the plugins however some of them should never change the contents, some of them can. The intention behind this is to catch development integration issues rather than runtime production issues. Having the object "locked" allows is to quickly identify plugins that are not coded as specified.
I've implemented something similar to your locked pattern, but also with a read-only interface implemented by a private sub-class containing the actual class data, so that you could pass out what is clearly a read-only view of the data and which can't be up-casted to the original 'mutable version'. The locking was purely to prevent the data provider from making further changes after it had provided an immutable view.
It worked reasonably well, but was a bit awkward, as you've noted. I think it's actually cleaner to have mutable 'Builder' objects which can then generate immutable snapshots. Think StringBuilder and String. This means you duplicate some property code and have to write the routines to do the copying, but it's less awkward, in my opinion, than having a write-lock on every property. It's also evident at compile-time that the snapshot is supposed to be read-only and the user of the Builder cannot modify the snapshots that it created earlier.
I would recommend this:
An immutable base class:
public class Wibble
{
public string Foo { get; private set; }
public string Bar { get; private set; }
public Wibble(string foo, string bar)
{
this.Foo = foo;
this.Bar = bar
}
}
Then a mutable class which you can change, and then create an immutable copy when the time comes.
public class MutableWibble
{
public string Foo { get; set; }
public string Bar { get; set; }
public Wibble CreateImmutableWibble()
{
return new Wibble(this.Foo, this.Bar);
}
}
I can't remember the C# syntax exactly, but you get the idea.
Further reading: http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=vs.71%29.aspx
You cannot make an object immutable!
You can follow this post:
How do I create an immutable Class?
But I think you can always change property values by reflection!
update
"...Actually, string objects are not that
immutable and as far as I know there are at least 2 ways to break string
immutability. With pointers as shown by this code example and with some advanced System.Reflection usage...."
http://codebetter.com/patricksmacchia/2008/01/13/immutable-types-understand-them-and-use-them/
The other option you have is use the BinaryFormatter to create a memberwise clone of the object to be "locked". Though you're not locking the object you're creating a snapshot which can be discarded while the original remains unchanged.

Categories

Resources