What is meant by immutable type and immutable property in C# ? can you g开发者_JAVA百科ive 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)
精彩评论