I am currently struggling to understand something i just saw somewhere.
Lets say I have two classes :
class MyFirstCLass{
public int membVar1;
private int membVar2;
public string membVar3;
private string membVar4;
public MyFirstClass(){
}
}
and :
class MySecondClass{
private MyFirstClass firstClassObject = new MyFirstClass();
public MyFirstClass FirstClassObject{
get{
return firstClassObject;
}
}
}
If i do something like this :
var secondClassObject = new MySecondClass(){
FirstClassObject = {membVar1 = 42, membVar3 = "foo"}
};
secondClass is an instanciation of MySecondClass, and does have one private member variable of type MyFirstClass wich has a readOnly property. However, i am able to change the state of membVar1 and membVar2. Isn't there any encapsulation problem ?
Best regards,
Al_th
The fact that the FirstClassObject property on MySecondClass has no setter does not mean that the object returned from the getter becomes immutable. Since it has public fields, these fields are mutable. Therefore it is perfectly legal to say secondClassObject.FirstClassObject.membVar1 = 42. The absence of the setter only means that you cannot replace the object reference stored in the firstClassObject field with a reference to a different object.
Please note: You are not changing the value of MySecondClass.FirstClassObject. You are simply changing the values inside that property.
Compare the following two snippets. The first is legal, the second is not as it tries to assign a new value to the FirstClassObject property:
// legal:
var secondClassObject = new MySecondClass(){
FirstClassObject = {membVar1 = 42, membVar3 = "foo"} }
// won't compile:
// Property or indexer 'FirstClassObject' cannot be assigned to -- it is read only
var secondClassObject = new MySecondClass(){
FirstClassObject = new MyFirstClass {membVar1 = 42, membVar3 = "foo"} }
Basically, your code is just a very fancy way of writing this:
var secondClassObject = new MySecondClass();
secondClassObject.FirstClassObject.membVar1 = 42;
secondClassObject.FirstClassObject.membVar3 = "foo";
And that's how I would write it. It is explicit and understandable.
Neither a storage location of type MyFirstCLass, nor the value returned by a a property of type MyFirstCLass, contains fields membVar1, membVar2, etc. The storage location or property instead contains information sufficient to either identify an instance of MyFirstCLass or indicate that it is "null". In some languages or frameworks, there exist reference types which identify an object but only allow certain operations to be performed on it, but Java and .NET both use Promiscuous Object References: if an object allows outside code that holds a reference to do something with it, any outside code that gets a reference will be able to do that.
If a class is using a mutable object to encapsulate its own state, and wishes to allow the outside world to see that state but not allow the outside world to tamper with it, it must not return the object directly to the outside code but instead give the outside code something else. Possibilities include:
Expose all the aspects of state encompassed by the object individually (e.g. have a membVar1 property which returns the value of the encapsulated object's membVar1). This can avoid confusion, but provides a caller with no way to handle the properties as a group.
Return a new instance of a read-only wrapper which holds a reference to the private object, and has members that forward read requests (but not write requests) to those members. The returned object will serve as a read-only "view", but outside code will have no nice way to identify whether two such objects are views of the same underlying object.
Have a field of a read-only-wrapper type which is initialized in the constructor, and have a property return that. If each object will only have one read-only wrapper associated with it, two wrapper references will view the same wrapped object only if they identify the same wrapper.
Create an immutable copy of the underlying data, perhaps by creating a new mutable copy and returning a new read-only wrapper to it. This will give the caller a "snapshot" of the data, rather than a live "view".
Create a new mutable copy of the underlying data, and return that. This has the disadvantage that a caller who tries to change the underlying data by changing the copy will be allowed to change the copy without any warnings, but the operation won't work. All of the arguments for why mutable structs are "evil" apply doubly here: code which receives an exposed-field structure should expect that changes to the received structure won't affect the source from which it came, but code which receives a mutable class object has no way of knowing that. Properties should not behave this way; such behavior is generally only appropriate for methods which make clear their intention (e.g. FirstClassObjectAsNewMyFirstClass();
Require that the caller pass in a mutable object of a type that can accept the underlying data, and copy the data into that. This gives the caller the data in a mutable form (which in some cases may be easier to work with) but at the same time avoids any confusion about who "owns" the object. As an added bonus, if the caller will be making many queries, the caller may reuse the same mutable object for all of them, thus avoiding unnecessary object allocations.
Encapsulate the data within a structure, and have a property return the structure. Some people may balk at such usage, but it's a useful convention in cases where a caller may want to piecewise-modify the data. This approach only really works if the data in question is limited to a fixed set of discrete values (such as the coordinates and dimensions of a rectangle), but has the advantage that if the caller understands what a .NET structure is (as all .NET programmers should) the semantics are inherently obvious.
Of these choices, only the last two make clear via the type system what semantics the caller should expect. Accepting a mutable object from the caller offers clear semantics, but makes usage awkward. Returning an exposed-field structure offers clear semantics but only if the data consists of a fixed set of discrete values. Returning a mutable copy of the data is sometimes useful, but is only appropriate if the method name makes clear what it is doing. The other choices generally leave ambiguous the question of whether the data represents a snapshot or a live "view".
Related
If there's a class which has a getter for an object, when the getter returns the object you can modify this object outside of its own class container, and this changes will be reflected when you read the object later with the getter again; so, I can't see the goal to set a setter for the object when the getter let me to read and modify the object as well.
Example:
You have a class called CashRegister and this class has an object called queue, if you read queue by means of a CashRegister's getter you can modify queue from the MainClass and the next time you invoke the CashRegister's getter the modifications previously made in MainClass will be present. By the way CLI.PrintAndJump() prints the content of a queue.
class MainClass
{
static void Main(string[] args)
{
Queue<int> tmpQueue, tmpQueue2;
CashRegister aCashRegister = new CashRegister();
tmpQueue = aCashRegister.GetCoinValues();
CLI.PrintAndJump(tmpQueue);
tmpQueue.Enqueue(10);
tmpQueue2 = aCashRegister.GetCoinValues();
CLI.PrintAndJump(tmpQueue2);
}
}
class CashRegister
{
Queue<int> coinValues = new Queue<int>(1);
public Queue<int> GetCoinValues()
{
return (coinValues);
}
}
Output:
1
1, 10
In a nutshell, if you need to modify the object queue, you don't need to set a setter for it (Is this method a good practice?), but what if I want the object to remain immutable?
Thanks.
In the context of C#, we typically talk about "setter" and "getter" methods in relation to a property, so it's kind of odd that your code example doesn't include any properties. But, let's ignore that for a moment, and assume that you might have a corresponding SetCoinValues() method.
The reason for such a method would be if you want to replace the entire Queue<int> object. There is a difference between modifying the Queue<int> object itself, which you can do with only a getter method, and replacing the Queue<int> object with a whole new one, which would require a setter method.
Why one might want to do this varies. It depends on the exact circumstance. And I think it's less likely one might want to replace a queue object, than say some other collection type (like an array or a list), or some other complex type other than a collection. But it could still happen.
Examples of complex types which are used as property values, or in terms of the non-property scenario, might have both a getter and setter method, include System.Windows.Media.Pen.DashStyle and System.Diagnostics.Process.StartInfo. The DashStyle object itself even has properties for setting and getting complex values, including the Dashes property, which is a collection of Double values.
I mention these to emphasize that this really has nothing at all to do with mutable vs. immutable. Both DashStyle and ProcessStartInfo are mutable types, but we still have properties which reference objects of those types and which have setter methods in addition to a getter.
The question of mutability (which seems to be the emphasis of the other answer) is a red herring, and will only distract you from what is really going on. The real point is that, even with mutable, complex types, there are times when you want to be able to replace the entire object, rather than modifying the object currently being held. In those cases, you need a setter method, so that you can change the actual reference for the property, instead of modifying the object the property refers to.
First of all, this is C#, not Java. In C#, we do not write getters and setters; we use properties instead. So, GetXyz() methods in C# are usually not getters, and they are very rarely paired with SetXyz() methods. For example, think of ICollection.GetLength(). Once we have established that, let's move on.
Read-write properties are primarily used for immutable values, an example of which are primitives. I hope you understand that you cannot get for example an int, change its value, and expect the value held by the containing object to also change. You have to put it back. And for this you need a writable property. But you have anticipated that, because in your question you are talking about objects.
Primitives are not the only entities that you cannot modify; there exist plenty of immutable structs and classes that behave the same way. If a property returns to you an object that simply does not offer any methods that you could use to alter its state, the only thing you can do is create a different instance of that object, and put it back in the containing object, for which of course you will need a writable property.
So, writable properties are necessary for writing back immutable entities.
When it comes to mutable objects, you are right, it does not make much sense to have a read-write property, because once you obtain a reference to the mutable object you can mutate it to your heart's content without ever having to "set" it back. For this reason, you will rarely see a setter for a mutable. But it happens some times. Peter Duniho covers an example of this in his answer. (It is mainly done for performance/convenience reasons, and the implied agreement in these cases is that the containing object does not have ownership of the object that is being set into it.)
I've a custom Entity class (see code below). The objects of this class get populated into a Dictionary collection Dictionary<string, Dictionary <uint,Entity>> dt . Someone ask me to use Struct instead of Class, since value types won't get copied into heap. Well, I think in this case Class seems better choice since Dictionary will then only contains reference to the objects of type Entity. Entity type in this case represents a row in a csv file. So for every row there will be a Entity type object. The encapsulated Dictionary within Entity type contains key,value pair representing column,value for a row in a csv file.
But I want to make sure I didn't miss anything obvious so thought better to ask.
public class Entity
{
Dictionary<string, string> dtValues = new Dictionary<string,string>(); //contains values from CSV file.
public Dictionary<string, string> Values
{
get { return dtValues; }
set { dtValues = value; }
}
}
Someone ask me to use Struct instead of Class, since value types won't get copied into heap.
That person is dead wrong. Simply put: the dictionary itself is on the heap, so its contents will also be on the heap.
If you're not sure whether your should use a reference type or a value type, then you should research the pros and cons of both (I listed a few here). But you should probably use a reference type.
Remember: premature optimization is the root of all evil.
Using a Dictionary of Structs is always a really bad idea because when you enumerate it or do anything with it's values you will be copying the data over and over, so using classes is the right way, in this manner only references are moved.
Types which hold references to mutable objects for the purpose of encapsulating state should generally avoid exposing those objects to outside code. I don't quite understand what the purpose of your Entity type would be, since the only apparent content is a reference to a Dictionary [which is, of course, a mutable type].
In general, if one wishes to store things in a collection and is trying to decide between using a class or a struct for the things to be stored, I would suggest the following:
If you use a mutable class type for list items or dictionary values [not keys], you may edit the information stored in an item without having to involve the collection itself in the process. Making information contained in an item available to outside code, however, will require either cloning the data item or copying data from it into something else.
If you use an immutable class type, or any structure type, for things stored in a collection, editing the information contained in an item will require reading out the item, producing a changed version, and storing it back. Making information contained in the item available to outside code, however, will be much easier, since one can return it as its own data type.
A pattern which is sometimes useful is to define a mutable structure type but then define a wrapper type something like the following:
public class ExposedFieldHolder<T>
{
public T Value;
ExposedFieldHolder(T value) { Value = value; }
}
If Value is a field, rather than a property, and one creates e.g. a Dictionary<string, ExposedFieldHolder<someStruct>>, then it will be possible to edit data while it's stored within the dictionary e.g.myDict["George"].Value.Age++;but it will also be possible to give the data associated with an entry to outside code [e.g.return myDict[name].Value;`].
Having a simple exposed-field structure encapsulated within an ExposedFieldHolder<T> can be safer and more convenient than simply using a mutable class (since one can return a holder's entire Value without giving outside code access to the holder itself), and also more convenient than using an immutable class or structure (since one can modify list items or dictionary values without having to use a readout-modify-writeback sequence). It is less space-efficient than simply storing an exposed-field structure directly in the collection. If one stored an exposed-field struct directly as a dictionary value without using an `ExposedFieldHolder, the above update to George's age would require the three-step process:
var temp = myDict["George"];
temp.Age++;
myDict["George"] = temp;
but that may still be better than what an immutable class or so-called "immutable" structure would require, e.g.
var temp = myDict["George"];
temp = new PersonDat(temp.Name, temp.Age+1, temp.FavoriteColor, temp.AstrologicalSign);
myDict["George"] = temp;
Note that if one consistently follows the former pattern when using exposed-field structures, the code will be correct regardless of what fields or properties the structure contains or the order in which they appear. By contrast, when using the latter pattern one must be very careful to ensure any fields or properties whose value should not be changed get passed to the constructor in the proper sequence. Some people may like that kind of code; I think it's horrible.
I want to make my class immutable. Obvious way would be to declare all fields as get; private set; and to initialize all fields in constructor. So clients must provide everything in constructor. The problem is that when there are ~10 or more fields passing them in constructor become very unreadable, because there are no labels for each field.
For example this is pretty readable:
info = new StockInfo
{
Name = data[0] as string,
Status = s,
LotSize = (int)data[1],
ISIN = data[2] as string,
MinStep = (decimal)data[3]
};
compare to this:
new StockInfo(data[0] as string, s, (int) data[1], data[2] as string, (decimal) data[3])
And now imaging that I have 10 or more parameters.
So how can I make class immutable saving readability?
I can suggest only use the same formatting when using constructor:
info = new StockInfo(
data[0] as string, // Name
s, // Status
(int)data[1], // LotSize
data[2] as string, // ISIN
(decimal)data[3] // MinStep
);
Can you suggest something better?
Here are some options. You will have to decide what's best for you:
Use a classic immutable object (with a massive constructor) with named arguments for readability. (Drawbacks: Some frown on having many constructor arguments. May be inconvenient to use from other .NET languages without support for named arguments.)
info = new StockInfo
(
name: data[0] as string,
status: s,
...
)
Expose the mutable object through an immutable interface. (Drawbacks: The object could still be mutated with casting. Extra type to write.)
public interface IStockInfo
{
string Name { get; }
string Status { get; }
}
IStockInfo info = new StockInfo
{
Name = data[0] as string,
Status = s,
...
}
Expose a read-only view of the mutable object - see ReadOnlyCollection<T> for example. (Drawbacks: Extra type to implement. Extra object created. Extra indirections.)
var readOnlyInfo = new ReadOnlyStockInfoDecorator(info);
Expose an immutable clone of the mutable object. (Drawbacks: Extra type to implement. Extra object created. Copying required.)
var immutableInfo = new ImmutableStockInfo(info);
Use freezable objects. (Drawback: Post-freeze mutation-attempts won't be caught until execution-time.)
info.Freeze();
info.Name = "Test"; // Make this throw an exception.
Use fluent-style builders or similar (Drawbacks: Some may be unfamiliar with the pattern. Lots of extra code to write. Lots of copies created. Intermediate states may possibly be illegal)
info = StockInfo.FromName(data[0] as string)
.WithStatus(s) // Make this create a modified copy
.WithXXX() ;
Here is how you could do it, using C#'s named parameters:
var info = new StockInfo
(
Name: data[0] as string,
Status: s,
LotSize: (int)data[1],
ISIN: data[2] as string,
MinStep: (decimal)data[3]
);
No, it is not possible. Either you have immutable object or you want to have ability to modify object.
You can use named parameters.
You may consider passing other objects (and group parameters), so that one object will contain only parameters that are somehow very similar.
Looking at your code I may also suggest that you extract parameters first, so instead of passing something like data[0] as string you use string stockName = data[0] as string; and then use stockName. That should make your code more readable.
If you're passing so many parameters to the constructor of your object it may be a good idea to revise your design. You may be violating Single Responsibility principle.
So how can I make class immutable saving readability?
You can use named parameters:
info = new StockInfo(
name: data[0] as string,
status: s,
lotSize: (int)data[1],
isin: data[2] as string,
minStep: (decimal)data[3]
);
Note that the goal of using object initializers is not readability - and they should not be considered a substitute for constructors. It is a very good idea to always include every parameter in a constructor which is required to properly initialize a type. Immutable types must pass in all of their arguments during construction, either via a constructor or a factory method.
Object initializers will never work with immutable types, as they work by setting values after constructors.
Some more possible solutions:
Immutability by convention
The object is mutable, you just behave well and never change it after it's been set-up. This is completely inappropriate for most uses (any where the object is public for a start), but can work well for internal "worker" objects with a limited number of places where they are used (and hence a limited number of places where you can mess up and change them).
Deeper Hierarchy
Assuming your real class has more than 5 fields (not that hard to read, especially if you've an IDE with tooltips), some may be composable. E.g if you had different parts of a name, and address and a latitude and longitude in the same class, you could break that into name, address and coördinate classes.
A bonus that happens in some such cases, is that if you've many (and I mean many for this to be worthwhile, anything less than a few thousand and it's a waste of time) such objects and there are some such fields identical between them, you can sometimes build them in such a way that those shared values have the same object in each case, rather than different identical objects - all the things that can go wrong with aliasing can't happen, since they are immutable after all.
Builder Classes
Examples would be StringBuilder and UriBuilder. Here you've got precisely the issue you have - you want the benefits of immutability, but there are at least some times when you want to be able to construct he object in more than one step.
So you create a different mutable class that has equivalent properties, but with setters as well as getters, along with other mutating methods (whether something like Append() makes sense depends on the class of course), and a method that constructs an instance of your immutable class.
I've made use of this with classes whose constructor has as many as 30 parameters, because there really were 30 different pieces of information that was part of the same concern. In this case, about the only place I'd call the constructor was in the corresponding builder class.
I would suggest that it may be helpful to have an interface for "maybe-mutable" objects which includes AsMutable, AsNewMutable, and AsImmutable methods. An immutable object could implelement AsImmutable by simply returning itself. A mutable object should implement AsImmutable by returning either a new immutable object created using the mutable one as a constructor parameter, or else an immutable object which is known to be equivalent. The constructor for the immutable object should load the new object with the contents of the original, but calling AsImmutable on all maybe-mutable fields.
A mutable object should simply return itself in response to AsMutable, while an immutable object should construct a new "shallowly" mutable object. If code wishes to mutate an object referred to by a "maybe-mutable" property, it should set the property to its AsMutable equivalent.
Calling the AsNewMutable method on an immutable object should behave just like AsMutable. Calling it on a mutable object could either behave equivalently to AsImmutable.AsMutable, or could create mutable clones of any nested mutable objects (there are times when either approach might be better, depending upon which nested objects will end up being mutated).
If you use this pattern, you should be able to reap many of the benefits of both immutable objects (most notably, the ability to take a snap shot of a "deep" object without needing to make a "deep" copy), and mutable ones (being able to produce an object by performing many steps on the same instance). Performance may be enhanced by having each a mutable object keep a reference to an immutable object whose state was at some time identical to its own; after constructing an immutable instance, the object could check whether it matches the other and, if so, discard the new instance and return the old one. While this would seem to represent extra work, it could in fact improve performance considerably in the scenario where a mutable object has AsImmutable called upon it more than once between mutations. If one calls AsImmutable twice on a deep tree structure when most of the tree has in fact not been mutated, having the non-mutated parts of the tree return the same object instances both times would facilitate future comparisons.
Note: If one uses this pattern, one should override GetHashCode and Equals for the deeply-immutable type, but not the mutable one. Immutable objects which hold identical values should be considered interchangeable and thus equivalent, but mutable objects should not be equivalent to anything but themselves regardless of their values. Note also that some care may be needed if objects hold anything of type double, float, or Decimal, since those types override Object.Equals to mean something other than equivalence.
From this Answer, I came to know that KeyValuePair are immutables.
I browsed through the docs, but could not find any information regarding immutable behavior.
I was wondering how to determine if a type is immutable or not?
I don't think there's a standard way to do this, since there is no official concept of immutability in C#. The only way I can think of is looking at certain things, indicating a higher probability:
1) All properties of the type have a private set
2) All fields are const/readonly or private
3) There are no methods with obvious/known side effects
4) Also, being a struct generally is a good indication (if it is BCL type or by someone with guidelines for this)
Something like an ImmutabeAttribute would be nice. There are some thoughts here (somewhere down in the comments), but I haven't seen one in "real life" yet.
The first indication would be that the documentation for the property in the overview says "Gets the key in the key/value pair."
The second more definite indication would be in the description of the property itself:
"This property is read/only."
I don't think you can find "proof" of immutability by just looking at the docs, but there are several strong indicators:
It's a struct (why does this matter?)
It has no settable public properties (both are read-only)
It has no obvious mutator methods
For definitive proof I recommend downloading the BCL's reference source from Microsoft or using an IL decompiler to show you how a type would look like in code.
A KeyValuePair<T1,T2> is a struct which, absent Reflection, can only be mutated outside its constructor by copying the contents of another KeyValuePair<T1,T2> which holds the desired values. Note that the statement:
MyKeyValuePair = new KeyValuePair(1,2);
like all similar constructor invocations on structures, actually works by creating a new temporary instance of KeyValuePair<int,int> (happens before the constructor itself executes), setting the field values of that instance (done by the constructor), copying all public and private fields of that new temporary instance to MyKeyValuePair, and then discarding the temporary instance.
Consider the following code:
static KeyValuePair MyKeyValuePair; // Field in some class
// Thread1
MyKeyValuePair = new KeyValuePair(1,1);
// ***
MyKeyValuePair = new KeyValuePair(2,2);
// Thread2
st = MyKeyValuePair.ToString();
Because MyKeyValuePair is precisely four bytes in length, the second statement in Thread1 will update both fields simultaneously. Despite that, if the second statement in Thread1 executes between Thread2's evaluation of MyKeyValuePair.Key.ToString() and MyKeyValuePair.Value.ToString(), the second ToString() will act upon the new mutated value of the structure, even though the first already-completed ToString()operated upon the value before the mutation.
All non-trivial structs, regardless of how they are declared, have the same immutability rules for their fields: code which can change a struct can change its fields; code which cannot change a struct cannot change its fields. Some structs may force one to go through hoops to change one of their fields, but designing struct types to be "immutable" is neither necessary nor sufficient to ensure the immutability of instances. There are a few reasonable uses of "immutable" struct types, but such use cases if anything require more care than is necessary for structs with exposed public fields.
I am wondering how immutability is defined? If the values aren't exposed as public, so can't be modified, then it's enough?
Can the values be modified inside the type, not by the customer of the type?
Or can one only set them inside a constructor? If so, in the cases of double initialization (using the this keyword on structs, etc) is still ok for immutable types?
How can I guarantee that the type is 100% immutable?
If the values aren't exposed as public, so can't be modified, then it's enough?
No, because you need read access.
Can the values be modified inside the type, not by the customer of the type?
No, because that's still mutation.
Or can one only set them inside a constructor?
Ding ding ding! With the additional point that immutable types often have methods that construct and return new instances, and also often have extra constructors marked internal specifically for use by those methods.
How can I guarantee that the type is 100% immutable?
In .Net it's tricky to get a guarantee like this, because you can use reflection to modify (mutate) private members.
The previous posters have already stated that you should assign values to your fields in the constructor and then keep your hands off them. But that is sometimes easier said than done. Let's say that your immutable object exposes a property of the type List<string>. Is that list allowed to change? And if not, how will you control it?
Eric Lippert has written a series of posts in his blog about immutability in C# that you might find interesting: you find the first part here.
One thing that I think might be missed in all these answers is that I think that an object can be considered immutable even if its internal state changes - as long as those internal changes are not visible to the 'client' code.
For example, the System.String class is immutable, but I think it would be permitted to cache the hash code for an instance so the hash is only calculated on the first call to GetHashCode(). Note that as far as I know, the System.String class does not do this, but I think it could and still be considered immutable. Of course any of these changes would have to be handled in a thread-safe manner (in keeping with the non-observable aspect of the changes).
To be honest though, I can't think of many reasons one might want or need this type of 'invisible mutability'.
Here is the definition of immutability from Wikipedia (link)
"In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created."
Essentially, once the object is created, none of its properties can be changed. An example is the String class. Once a String object is created it cannot be changed. Any operation done to it actually creates a new String object.
Lots of questions there. I'll try to answer each of them individually:
"I am wondering how immutability is defined?" - Straight from the Wikipedia page (and a perfectly accurate/concise definition)
An immutable object is an object whose state cannot be modified after it is created
"If the values aren't exposed as public, so can't be modified, then it's enough?" - Not quite. It can't be modified in any way whatsoever, so you've got to insure that methods/functions don't change the state of the object, and if performing operations, always return a new instance.
"Can the values be modified inside the type, not by the customer of the type?" - Technically, it can't be modified either inside or by a consumer of the type. In pratice, types such as System.String (a reference type for the matter) exist that can be considered mutable for almost all practical purposes, though not in theory.
"Or can one only set them inside a constructor?" - Yes, in theory that's the only place where state (variables) can be set.
"If so, in the cases of double initialization (using the this keyword on structs, etc) is still ok for immutable types?" - Yes, that's still perfectly fine, because it's all part of the initialisation (creation) process, and the instance isn't returned until it has finished.
"How can I guarantee that the type is 100% immutable?" - The following conditions should insure that. (Someone please point out if I'm missing one.)
Don't expose any variables. They should all be kept private (not even protected is acceptable, since derived classes can then modify state).
Don't allow any instance methods to modify state (variables). This should only be done in the constructor, while methods should create new instances using a particular constructor if they require to return a "modified" object.
All members that are exposed (as read-only) or objects returned by methods must themselves be immutable.
Note: you can't insure the immutability of derived types, since they can define new variables. This is a reason for marking any type you wan't to make sure it immutable as sealed so that no derived class can be considered to be of your base immutable type anywhere in code.
Hope that helps.
I've learned that immutability is when you set everything in the constructor and cannot modify it later on during the lifetime of the object.
The definition of immutability can be located on Google .
Example:
immutable - literally, not able to change.
www.filosofia.net/materiales/rec/glosaen.htm
In terms of immutable data structures, the typical definition is write-once-read-many, in other words, as you say, once created, it cannot be changed.
There are some cases which are slightly in the gray area. For instance, .NET strings are considered immutable, because they can't change, however, StringBuilder internally modifies a String object.
An immutable is essentially a class that forces itself to be final from within its own code. Once it is there, nothing can be changed. In my knowledge, things are set in the constructor and then that's it. I don't see how something could be immutable otherwise.
There's unfortunately no immutable keywords in c#/vb.net, though it has been debated, but if there's no autoproperties and all fields are declared with the readonly (readonly fields can only bet assigned in the constructor) modfier and that all fields is declared of an immutable type you will have assured your self immutability.
An immutable object is one whose observable state can never be changed by any plausible sequence of code execution. An immutable type is one which guarantees that any instances exposed to the outside world will be immutable (this requirement is often stated as requiring that the object's state may only be set in its constructor; this isn't strictly necessary in the case of objects with private constructors, nor is it sufficient in the case of objects which call outside methods on themselves during construction).
A point which other answers have neglected, however, is a definition of an object's state. If Foo is a class, the state of a List<Foo> consists of the sequence of object identities contained therein. If the only reference to a particular List<Foo> instance is held by code which will neither cause that sequence to be changed, nor expose it to code that might do so, then that instance will be immutable, regardless of whether the Foo objects referred to therein are mutable or immutable.
To use an analogy, if one has a list of automobile VINs (Vehicle Identification Numbers) printed on tamper-evident paper, the list itself would be immutable even though cars aren't. Even if the list contains ten red cars today, it might contain ten blue cars tomorrow; they would still, however, be the same ten cars.