15

We know the concept of immutability but need to know few immutable types other than

  • String
  • DateTime

Are there more?

Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
  • 1
    Most people know only about String, leave alone DateTime. So i am creating a question to help our developers community. – Nikhil Agrawal Jul 30 '15 at 10:52
  • 3
    Re: creating a list of immutable types for easy reference. Good idea, but perhaps it would be best to have only a single (community wiki) answer that everyone can extend; otherwise we'll end up with tons of answers where most of which are likely to list only a smallish subset of immutable types in the framework. – stakx - no longer contributing Jul 30 '15 at 11:02

5 Answers5

22

A list of immutable types in the framework class library follows below. (Feel free to expand it!)

System.…

  • All primitive value types: (Note: not all value types are immutable!)
    • Byte and SByte
    • Int16 and UInt16
    • Int32 and UInt32
    • Int64 and UInt64
    • IntPtr
    • Single
    • Double
  • Decimal
  • All anonymous types created by the compiler (new { ... } in C#, New With { ... } in VB.NET) (Wrong for two reasons: These types are not in the FCL, and apparently VB.NET types are mutable.)
  • All enumeration types (enum, Enum)
  • All delegate types. (see this answer. While it might seem that delegates are mutable (since you can do things like obj.PropertyChanged += callback, it's actually the obj.PropertyChanged reference that is mutated to point to a newly constructed delegate instance; the original delegate instance stays unchanged.)
  • DateTime, TimeSpan (mentioned in this answer) and DateTimeOffset
  • DBNull
  • Guid
  • Nullable<T>
  • String
  • The Tuple<…> types introduced with .NET 4 (mentioned in this answer)
  • Uri
  • Version
  • Void

System.Linq.…

  • Lookup<TKey, TElement>
Community
  • 1
  • 1
stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
  • 3
    Wouldn't it be easier to just say "all value types" + the non-value-type exceptions, such as String, Tuple, and Uri? – Dave Doknjas Jul 30 '15 at 14:09
  • 1
    @DaveDoknjas: Difficult to tell whether that would really be easier, because the list of exceptions is not as short as you might assume. For example, [many `IEnumerator<>` implementations are mutable value types](http://stackoverflow.com/questions/3168311/why-do-bcl-collections-use-struct-enumerators-not-classes). – stakx - no longer contributing Jul 31 '15 at 06:09
  • But the list of value types is quite large. – Dave Doknjas Jul 31 '15 at 13:59
  • You never know what value types will be added to the framework later, so listing only exceptions seems unsafer than explicitly listing already known types; even if the list gets longer. The OP wanted a list of type names, anyway. – stakx - no longer contributing Jul 31 '15 at 20:42
  • 1
    You're missing enums and anonymous types. – nawfal Aug 02 '15 at 05:13
  • Not to forget anonymous types can be mutable in VB.NET. – nawfal Aug 02 '15 at 13:16
  • What about the `object` type in C#? I expected it to also change when changed in a called method. I tested this, it looks like the object type is also immutable. – Ozkan Oct 05 '17 at 10:29
  • @Ozkan: given an actual instance of `object` (i.e. a value with a run-time type of `object`), yes; but since you can derive from `object`, you can't say that anything with a static (compile-time) type of `object` is immutable. None of the types mentioned on this list allow subclassing in the usual .NET languages (`Delegate` can be subclassed in IL but not in C# or VB.NET), so polymorphism doesn't come into the picture. – stakx - no longer contributing Oct 05 '17 at 12:00
  • should be void with a lowercase 'v' – kofifus Jul 06 '20 at 23:26
  • @kofifus - No. `void` is the C# keyword for the FCL type named `System.Void`. The above list contains FCL type names. – stakx - no longer contributing Jul 10 '20 at 20:59
1

I am not sure if you're looking for publicly immutable types in .NET or types totally immutable at all. Furthermore you want to take care of only the public types in .NET? The deeper problem is defining what forms immutability. Does a class that only has

public readonly int[] Numbers;

makes it immutable? The Numbers itself can't be changed but its contents can be. You get the idea.

Anyway you could inspect yourself programmatically. For deeper nested checks you will need recursion (which I wont do here)

Load all assemblies you wanna check, and do something like (not tested)

var immutables = AppDomain.CurrentDomain
                .GetAssemblies()
                .SelectMany(t => t.GetTypes())
                .Where(t => t
                           .GetProperties(your binding flags depending on your definition)
                           .All(p => !p.CanWrite) 
                         && t
                           .GetFields(your binding flags depending on your definition)
                           .All(f => f.IsInitOnly)
                .ToList();

Even this wont be enough for finding immutability of collection types. Some of the immutable collection types (though not a part of default .NET core) can be found here: Immutable Collections


Some notable immutables:

  • some class types like String, Tuple, anonymous types
  • most structs (notable exceptions include most enumerators)
  • enums
  • delegates
  • immutable collection types like

    ImmutableArray (prerelease version)

    ImmutableDictionary

    ImmutableSortedDictionary

    ImmutableHashSet

    ImmutableList

    ImmutableQueue

    ImmutableSortedSet

    ImmutableStack

nawfal
  • 70,104
  • 56
  • 326
  • 368
0

TimeSpan, or modern type family Tuple. Tuple is immutable cause it implemented to support functional languages (F# f.e.) in .NET.

Of course you can make your own classes and structures mutable or immutable, as you wish. Immutable types (aka value objects) are useful in multithreading programming, functional programming, to clear a code.

To make a class or struct immutable just remove all public/protected/internal setters; and better declare all fields with readonly keyword.

Mark Shevchenko
  • 7,937
  • 1
  • 25
  • 29
  • just to be clear, just because value types happen to be immutable does not mean that all immutable objects are value types.... – Claies Jul 30 '15 at 10:55
  • A type that changes it's internal state without it being osbervable from the outside can be immutable: for example an expensive property is evaluated lazily once and the result is then cached. Immutable types do not necessarily imply `readonly` fields. – InBetween Jul 30 '15 at 11:00
  • @Claies, yes, of course. *Value object* in my text is a pattern name, not .NET value type. This pattern described by [Eric Evans](http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215) f.e. – Mark Shevchenko Jul 30 '15 at 11:13
  • @InBetween, you're right. However, this possibility suggests the class has two responsibilities at least. This violates [one of the principles](https://en.wikipedia.org/wiki/Single_responsibility_principle) of OO design. So, you may do it, but you shouldn't. – Mark Shevchenko Jul 30 '15 at 11:19
  • @MarkShevchenko :) Once I wrote the comment I started thinking about it a bit more and I ended up asking on SO because I'm not really sure what the correct answer is. Is such a type immutable or not? I see you spotted the question :p I tend to think it is. – InBetween Jul 30 '15 at 11:37
0

Some examples from mscorlib:

  • All of the primitive types
  • enums
  • decimal
  • (U)IntPtr
  • DateTime, DateTimeOffset, TimeSpan
  • KeyValuePair<,> - as an opposite, DictionaryEntry is not immutable
  • Tuple<...>
  • (Multicast)Delegate - similarly to strings, always a new instance is returned when it is changed.
  • Guid
  • Version

Interestingly, string is actually not really immutable; however, we can treat it as a "practically immutable" type, meaning, that the content of a string instance cannot be changed by the public ways (at least, in a safe context). But it has for example a wstrcpy internal method, which is used by the StringBuilder class to manipulate a string instance.

György Kőszeg
  • 17,093
  • 6
  • 37
  • 65
0

With .NET 5 and new C# 9.0 release pretty much every object can be immutable now (or contain immutable state in properties)

More about it here: https://martinstanik.com/2020/10/09/immutable-data-types-after-net-5-release/

st35ly
  • 1,215
  • 18
  • 24