Immutable type and property in C# - c#

What is meant by immutable type and immutable property in C# ? can you give simple example?

An immutable type is a type of which its properties can only be set at initialization. Once an object is created, nothing can be changed anymore. An immutable property is simply a read-only property.
In the following example, ImmutableType is an immutable type with one property Test. Test is a read-only property. It can only be set at construction.
class ImmutableType
{
private readonly string _test;
public string Test
{
get { return _test; }
}
public ImmutableType(string test)
{
_test = test;
}
}
See also: The Wikipedia article, and some Stack Overflow questions on the topic.

In addition to #fretje's answer above, in C#6 and later, getter-only auto properties have now been implemented, which allows for immutable auto-properties without the need for the additional explicit private readonly backing field. The equivalent code would be abbreviated to:
class ImmutableType
{
public string Test
{
get; // No Set at all, not even a private set.
}
public ImmutableType(string test)
{
Test = test; // The compiler understands this and initializes the backing field
}
}
Note that private set only provides a restricted encapsulation of change to the property from within the same class, and thus isn't truly immutable:
public string Test
{
get;
private set; // Not immutable, since this is still mutable from within the class
}
More about immutability
As others have said, an immutable Property is a property which cannot change once it has been set. Setting of the 'only' value is done during construction.
An immutable Type is a type where all (externally visible) properties and fields are immutable - for example the "Record" Type originally scheduled for C#7 (hopefully now 8) would have been an immutable type. Other examples of Immutable Types are Tuples, and all anonymous classes.
Immutable fields should be qualified with the readonly keyword in C# - this is enforced by the compiler to ensure that no other code attempts to change the field outside of the constructor.
Wherever possible, immutability of fields, variables and properties is regarded as good practice, as this greatly reduces the surface area for bugs (since fields represent the state of an object, preventing change to fields reduces the number of states).
The benefit of immutability is especially important in multi-threaded programs, where two or more threads concurrently access the same object. Since multiple concurrent reading threads can safely read the value of a field or property, the programmer doesn't need to be concerned about thread safety issues relating to change to the field by other threads (because change to the property is prohibited)
One common drawback of immutability when dealing with complex objects consisting of multiple composed objects, is that the entire graph needs to be built 'in one go', which can lead to messy code. A common solution here is to use the Builder pattern as a scaffold, which allows a transient, mutable representation to be built in steps, and then the final, immutable object is obtained in the final .Build() step.

fretje is correct. The most popular example of an immutable type is a string object in C#. This is the entire reason that StringBuilder exists.

There is no clear definition for immutability in C#:
It usually entails all public fields to be readonly and all public properties to have init setter or no setter.
It may also extend this to private members (although it is common to use mutable private members to cache values ie the hashcode)
It may also mean all members are themselves of immutable types. As otherwise a consumer can still modify the object by calling a member method
It may also mean all methods always return the same output when called with the same arguments. In particular an immutable GetHashCode() means the object is safe to use as a key in dictionaries etc
A stronger and often more useful concept is that of - 'Data' an Immutable type which also has value semantics (usually by inheriting from IEquatable<T>)
Here is an example of a 'Data' type that satisfies all of the demands above:
record MyData(int age, DateTime JoinDate);
(see project F for more on how Data types are useful)

Related

Standard way of returning an internal collection as IEnumerable<T>

Say I have:
class foo
{
private List<T> bar;
public IEnumerable<T> GetBar();
}
where GetBar() should return that very same List, without exposing internals (i.e. no other class should be able to remove elements from the internal list, reorder it etc.) and avoiding excessive copying. What is the standard way to do this?
If you want to return an immutable list, return bar.AsReadOnly().
Typically the member that exposes this readonly wrapper would be of type IList<T>. I would only downcast to IEnumerable<T> if I wanted to indicate to the consumer that the implementation might use lazy enumeration.
Personally I'd make it a property, and return the same readonly wrapper on each invocation:
class Foo
{
private List<T> bar;
private IList<T> readonlyBar;
public Foo()
{
bar = ...;
readonlyBar = bar.AsReadOnly();
}
public IList<T> Bar
{
get { return readonlyBar; }
}
}
You can return an instance of ReadOnlyCollection from your method:
return new ReadOnlyCollection(items);
A property which encapsulates part of an object's mutable state may, if the type is a mutable class, represent any of these:
A live mutable view of the property's state
A mutable view of a detached copy of the property's state
A mutable view of a state that may or may not remain attached to the property's state
If the type is read-only, but not guaranteed to be immutable, it may represent any of these:
A guaranteed-"live" read-only view of the property's state
An immutable copy of the state as of the time it was called
A view of a state that may start out being attached to the property's state, but may or may not remain attached.
While the type of the determined object may be used to distinguish the first set of three behaviors from the latter set, I know of no standard convention to indicate, in the absence of a suitable guaranteed-immutable return type, which of the behaviors within the appropriate set applies. Since there is no guaranteed-immutable implementation of IEnumerable<T> that would seem applicable here, your best bet is probably to use Joe's code, but also document your behavior as #3. Unless you can think of some reason clients would benefit from #2, documenting your behavior as #3 will give you the most flexibility to change your implementation in future should that be necessary. For example, if thread-safe access ends up being necessary in the future, your class could implement an internal method which locks the collection long enough to copy it to an array and returns that array (possibly wrapped in ReadOnlyCollection<T>, though it probably wouldn't matter) cast as IEnumerable<T>. Such an approach wouldn't work if the property was supposed to represent a live view.

Is a class immutable if its readonly fields are not immutable?

If I have a C# class with only readonly fields, but the fields' types are NOT immutable, is the class considered immutable?
Is this class immutable?
public class Foo
{
private readonly int[] _blah;
public Foo(int[] blah)
{
_blah = blah;
}
public int[] Blah { get { return _blah; } }
}
_blah is not immutable, since I can change the members of the array, though the array member variable can never change.
So, is a class immutable if its fields are all readonly, or is a class immutable only if its fields are not only readonly, but also immutable themselves?
It will really depend on who you ask or what you mean. Some might say that the class itself is immutable because its direct members are immutable. Some might say that the class and all its members (and their properties, etc) -- basically, the entire object graph -- must be immutable in order to be considered immutable.
private field arrays marked as readonly are immutable, but that doesn't mean you can't replace the indexes with different values. A way to solve this is to return a copy of the array or an enumeration of the array
The objects of the array may or may not be immutable. Whether you make them immutable or you return clones of the them or whatever, that's really up to you.
In your situation, the objects are integers (which are immutable), but your array itself isn't (again, depending what you define as immutable). If all you want to guarantee is the private field can't be altered and don't care about the indexes, then you're fine. But, if you want the indexes to be locked in then you need to expose your array in another way.
Also, a nice collection to look into is the ReadOnlyCollection<T>. It is a collection that holds a reference to the original collection (it wraps it), so that the indexes can't be changed.
Also, point in case... already you have varying answers to the degree of what "immutable" actually means.
Instances of this class are not immutable, because you can mutate their contents. E.g. foo.Blah[0] = 42;. But if you changed the Blah property to IEnumerable<int> or IReadOnlyList<int>, the instances would be considered immutable.
This class is not immutable since it can be inherited and have other things added it.
I think its immutable if it follows three principals:
Make the fields private readonly.
Provide a public property get accesor.
If the class is not longer needed to be inherited, make it sealed.
These are not hard and fast rules with a strict definition of immutable. They are just guidelines.

What is the difference between `Fields` and `Properties` in C#? [duplicate]

This question already has answers here:
What is the difference between a field and a property?
(33 answers)
Closed 8 years ago.
Edit, as per these comments:
Do you mean "Property" vs "Field"?
public String S1; vs public String S2
{ get; set; } – dana
Exactly dana, i mean the same. – Asad
Asad: you really need to try to use
some other term to describe what you
mean so that we can better understand
your question. C# does not have global
variables. The fields you can define
in C# are not global - they are
members of the class type. – dthorpe
Hi fellas,
Need your expert views over the difference between Field and Property. As in my project, I have used certain global variables which later on i changed to 'Properties' . My manager is asking what is the benefit of using Properties of variables instead of Fields.
Although I have replied him that Property provides a kind of secure/safe/indirect access to Field instead of modifying them directly if they are declared public or protected. But Please provide me with some more convincing arguments.
Thanks and Regards
#Asad:
You should get your terminology right: Fields are not Global Variables, C# does not have global variables (as a few commenters mentioned: you can simulate global variables, but you should not do that).
The main advantage is that you can attach all sorts of functionality to a property such as validation, synchronization etc. You can't do that for a class field. For example, a field can throw BCL exceptions on assignment but it can't throw an exception that make sense with logic in your problem domain.
Also imagine trying to protect a field for thread synchronization. You have to write extra code in all the places in your code where the field is accessed. To do that with a property you can simply wrap the getter and setter with a lock in one place. (But beware! The ease of using lock in property getters and setters can give you a false sense of security if you're working with mutable types. See the accepted answer in this post.)
Now, you might think that validation and synchronization are not important to you for this particular value, and they may never be for this particular instance. But by using properties instead of direct field access is making your application much more maintainable in the future. (Suppose the value of an integer field suddenly needs to come from a source different from the original implementation and it needs to be converted from a string to an int. If you use properties to wrap the field then you make the change in one place and all the client code that uses that property does not need to change at all!)
Also, for managing information shared across many classes (global) take a look at the singleton pattern. But beware! Even though it looks neat and clean you can still get into trouble with it. Though if you really need global data you should use properties contained in a singleton. If nothing else, it's a good organization strategy.
To avoid issues with singletons or "global" data take a look at dependency injection as a much better alternative.
C# syntax doesn't have a "global variable" declaration. It has properties and fields, and static properties and fields.
If by "global variable" you mean a static field or static property, that is different from a property or field in that the static field or property is not stored in the object instance data, it is stored in global memory. The value assigned to a static field or property is accessible to all instances of that class, and all instances see the same value. A static field is the closest thing C# has to the notion of "global variable" found in other programming languages.
A non-static property or field stores its data in the object instance data, so each instance of the object has its own local copy. Modifying object1.A property will not affect the value of object2.A property.
Have a look at Properties (C# Programming Guide)
A property is a member that provides a
flexible mechanism to read, write, or
compute the value of a private field.
Properties can be used as if they are
public data members, but they are
actually special methods called
accessors. This enables data to be
accessed easily and still helps
promote the safety and flexibility of
methods.
Properties enable a class to expose a
public way of getting and setting
values, while hiding implementation
or verification code.
A get property accessor is used to
return the property value, and a set
accessor is used to assign a new
value. These accessors can have
different access levels.
Properties that do not implement a
set accessor are read only.
I prefer properties because then when I use them in code I know exactly which class was used to call them (ex. class.property = value). Public class variables can become a real pain and waste of time when you are trying to figure out where they came from during debugging.

How to instantiate a large immutable type?

I have a type with about 40 properties (all value types) that represents a type of transaction for my business. An instance of this class corresponds to a row in my database. I would like to keep my class immutable since it will only ever be used for read operations, but I am not sure how to go about setting 40 properties during initialization.
Typically I use constructor initialization for immutable types, but I would like to avoid writing a constructor with 40 parameters. The setters for my properties are currently private though I am willing to change with good enough reason. Is there a common way to handle this situation or a better way to approach the problem?
Your problem isn't so much a constructor with 40 arguments, but a class with 40 fields.
I'd recommend breaking this down. Are any of the fields related in some way? If so, group them into a common object (e.g. EmailInfo), then have your big object just reference the grouping objects.
// Instead of this:
foo.EmailHeader
foo.EmailSubject
foo.Email...
// Do this:
foo.Email.Header
foo.Email.Subject
Once your class has fewer direct properties, creating a constructor that takes those grouping objects isn't so terrible.
Quick point. You mentioned your setters on the object are private. If that is the case then your object is not immutable (otherwise setters couldn't exist). At best your object is read only.
For a true immutable object there is no choice but to have the constructor take in all of the values necessary to initialize the object. The best way to reduce the number of parameters in the constructor is to group the values into bigger objects which are then passed to the constructor. Although I wouldn't do that unless the values are otherwise logically related.
If your immutable type does truly need the 40 values and they are otherwise unrelated, the best approach is to have a constructor with 40 values. That or further break down the big immutable object.
I like the approach of using a mutable object to instantiate an immutable object; the mutable object is just for tidy passing of options. One example of this in the .NET framework is ProcessStartInfo.
class XInfo {
public int A;
public int B;
}
class X {
public X (XInfo i) {
// you can transform the data/layout from i any way you need
..
}
}
new X(new XInfo() {
A = 42
})
While I'll hold my tongue about the '40 properties', I find the above approach works pretty well. An added bonus is the XInfo and the internal structure used in X can be entirely different, as long as you can provide a sane mapping.
If i go by your words "but I am not sure how to go about setting 40 properties during initialization.", it appears that your problem is a class with too many fields/properties.
Doesnt seem to be a problem of making it immutable, because you already know how to do that.
I would suggest (like others), Refactor and Extract Class.
As an alternative, you can make your class derive from freezable, I think this may be the solution you are searching for. You can Instatiate the object, set the values, then set it frozen. Once you set it frozen the class is 'read only'.
I would suggest putting the parameters into one or more structures, and having the object hold those structures. Nesting objects would be possible, but would add more overhead than nesting structures.
As an alternative, you could create an abstract base class with "readonly mustoverride" versions of all your properties. From this, derive a mutable and immutable object class. The immutable one can accept the base class in its constructor, and use all the readonly properties to build the new object. The mutable class can provide a means of writing the properties using methods, read-write properties with different names from the readonly versions, etc.

Doesn't this defeat the whole purpose of having read-only properties?

I know how to use properties and I understand that they implicitly call underlying get and set accessors, depending on whether we are writing to or reading from a property.
static void Main(string[] args)
{
A a = new A();
(a.b).i = 100;
}
class A
{
private B _b = new B();
public B b
{
get { return _b; }
}
}
class B
{
public int i;
}
What code (a.b).i = 100; essentially does is that first property’s get accessor returns a reference to an object _b, and once we have this reference, we are able to access _b’s members and change their values.
Thus, in our example, having read only property only prevents outside code from changing the value of a reference variable _b, but it doesn’t prevent outside code from accessing _b’s members.
So it seems that property can only detect whether we are trying to read from or write to a variable ( in our case variable _b ) located on the stack, while it’s not able to detect whether we’re trying to also write to members of an object to which the variable on the stack ( assuming this variable is of reference type ) points to.
a) But doesn’t that defeat the whole purpose of having read-only properties? Wouldn’t it be more effective if properties had the ability to also detect whether we’re trying to access members of an object returned by get accessor( assuming backing field is of a reference type )?
thank you
Immutability is not transitive; you can't expect mutable objects into an immutable accessor to be immutable.
Your reference is read only, not your object.
Imagine a class like this:
public class A
{
private List<int> _myList<int> = new List<int>();
public List<int> MyList { get { return _myList; } }
}
Now, users of the class can add and remove and access items in the list, but they cannot replace the list itself. This is important. It allows you to do things inside the class like assume the _myList member is never null, for example.
Put a more general way, this paradigm allows you do define an interface into your class such that users can use the types in the properties you expose, but they cannot just swap instances of complex types out from under you.
No, it does not defeat the purpose of read-only properties.
It is possible to use read-only properties that don't let the user change the underlying data. For example, you can have your property return a System.Collections.ObjectModel.ReadOnlyCollection even though the underlying type is a List. This, of course, won't prevent the user from changing the properties of the items in the collection.
Of course you can access B.i; it's public. You're thinking that since _b is private, all methods should be private when fetched through A? In that case it's pretty useless as you wouldn't be able to use B for anything.
You ask:
Doesn’t that defeat the whole purpose
of having read-only properties?
But look: your B.i member is a public field.
I ask you, then: what is the purpose of having a public field? It only makes sense if you want users of your code to be able to change that field's value. If you don't want that, it should be a private field, or (if you want to provide read but not write access) a property with a private set accessor.
So there's your answer. private B _b serves its purpose in the code you posted quite well (_b cannot be externally set to something new), just as public int i serves its purpose equally well (i can be externally changed).
Reference immutability is a popular feature request. Too bad its is so dramatically non CLS compliant. Very few languages have this notion, I only know of C++ (but don't get out much).
The key problem that this needs to be enforced by the CLR. C++ doesn't need to enforce this at runtime, only a C++ compiler is required to ensure that const contracts are observed. It has no support at all for language interop, beyond a bolt-on like COM.
This won't fly in .NET, there's little point in declaring a reference immutable and have that verified by the compiler when another language can stomp all over it because it doesn't have the syntax to express immutability. I reckon we'll get it some day, not Real Soon.
As a minor point, you don't have to write (a.b).i = 100; but simply
a.b.i = 100;
Back to your question, I don't think it defeats the purpose. You can still not do the following:
a.b = new B();
because there's no public set(). If you want the member i of class B to be read only, you can do the same thing as you did to member _b of class A by making it private and providing a public get(), but not set(). Off the top my head, doing what you propose might lead to many unexpected consistencies (I'm sure the language designers did not overlook this).
Entirely dependent on the situation, but read only access to a mutable object is a commonly used design. In many cases you simply want to ensure that the object itself remains the same.
Some classes (like String object in Java, and I believe in C# as well) are entirely immutable, where as others are only partially mutable. Consider an ActiveRecord style of object for which most fields are mutable, but the ID is immutable. If your class holds an ActiveRecord in a read only property, external classes cannot swap it for a different ActiveRecord object and thus change the ID, which might break assumptions within your class.
I disagree. Your property is for the class B, not for the members of class B. This means you can't assign a new Object to b. It doesn't mean that B's public members suddenly become private.
readonly applies to the class property, not the object that the property refers to. It keeps you from being able to write a.b = new B();, and that is all it does. It places no constraints on what you can do to the object once you get a reference to it. I think what you are discovering is that readonly make the most sense when applied to value types or immutable class types.
Another use case:
interface INamedPerson
{
String Name { get; }
}
class Bob : INamedPerson
{
public String Name { get; set; }
}
class Office
{
// initialisation code....
public INamedPerson TheBoss { get; }
public IEnumerable<INamedPerson> Minions { get; }
}
Now, if you have an instance of the Office, as long as you don't go cheating with casts, you have read-only access to everyone's names, but can't change any of them.
Ah. Encapsulation does the instantiated class inherit the containing class's access level. Exposing type B as a public property of type A. 'B.i' is public so it should be accessible from outside the same way 'A.b' is public.
A.b returns a reference of a privately accessible type B, however type B has a publicly accessible field i. My understanding is that you can set the i field of B but you can't set the b property of A externally. The B type property of A is readonly however the reference to type B does not define the same readonly access to its fields.
I'm sure you can modify the definition of type B to suit your need for the access level of B's fields or properties.

Categories

Resources