Вопрос: Примеры неизменяемых типов в .Net


Мы знаем понятие неизменности, но нам нужно знать несколько неизменных типов, кроме

  • строка
  • DateTime

Есть ли еще?


8


источник


Ответы:


Ниже приведен список неизменяемых типов в библиотеке классов framework. (Не стесняйтесь его расширять!)

System.…

  • Все примитивные типы значений: (Заметка: не все типы значений неизменяемы !)
    • Byte а также SByte
    • Int16 а также UInt16
    • Int32 а также UInt32
    • Int64 а также UInt64
    • IntPtr
    • Single
    • Double
  • Decimal
  • Все анонимные типы, созданные компилятором ( new { ... } в C #, New With { ... } в VB.NET)   (Неправильно по двум причинам: эти типы не находятся в FCL, и, видимо, типы VB.NET изменяемы.)
  • Все типы перечисления ( enum, Enum)
  • Все типы делегатов. (видеть этот ответ , Хотя может показаться, что делегаты являются изменяемыми (поскольку вы можете делать такие вещи, как obj.PropertyChanged += callback, это на самом деле obj.PropertyChanged ссылка, которая мутирована, чтобы указать на вновь созданный экземпляр делегата; исходный экземпляр делегата остается неизменным.)
  • DateTime, TimeSpan  (упоминается в этот ответ )  а также DateTimeOffset
  • DBNull
  • Guid
  • Nullable<T>
  • String
  • Tuple<…> типы, введенные с .NET 4 (упоминается в этот ответ )
  • Uri
  • Version
  • Void

System.Linq.…

  • Lookup<TKey, TElement>

10



TimeSpan, или семья современного типа Tuple, Tuple он неизменен, потому что он реализован для поддержки функциональных языков (F # f.e.) в .NET.

Конечно, вы можете сделать свои собственные классы и структуры изменчивыми или неизменными, как вы пожелаете. Неизменяемые типы (как объекты значения) полезны при программировании многопоточности, функциональном программировании, для очистки кода.

Чтобы сделать класс или структуру неизменяемыми, просто удалите все общедоступные / защищенные / внутренние сеттеры; и лучше объявить все поля с помощью readonly ключевое слово.


1



Я не уверен, что вы ищете абсолютно неизменяемые типы в .NET или типы, абсолютно неизменяемые вообще. Кроме того, вы хотите заботиться только о публичных типах в .NET? Более глубокая проблема заключается в определении того, какие формы неизменяемы. Имеет ли класс, который имеет

public readonly int[] Numbers;

делает его неизменным? Сам номер не может быть изменен, но его содержимое может быть. Вы поняли эту идею.

В любом случае, вы можете проверить себя программно , Для более глубоких вложенных проверок вам понадобится рекурсия (которую я не буду делать здесь)

Загрузите все сборки, которые вы хотите проверить, и сделайте что-нибудь вроде (не проверено)

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();

Даже этого не будет достаточно для поиска неизменности типов сбора. Некоторые из неизменяемых типов коллекций (хотя и не являются частью ядра .NET по умолчанию) можно найти здесь: Неизменяемые коллекции


Некоторые заметные непреложности:

  • некоторые типы классов, например String, Tuple, анонимные типы
  • большинство структур (заметные исключения включают большинство счетчиков)
  • перечислений
  • делегаты
  • неизменяемые типы коллекций

    ImmutableArray (предварительная версия)

    ImmutableDictionary

    ImmutableSortedDictionary

    ImmutableHashSet

    ImmutableList

    ImmutableQueue

    ImmutableSortedSet

    ImmutableStack


1



Некоторые примеры из mscorlib :

  • Все примитивные типы
  • перечислений
  • decimal
  • (U)IntPtr
  • DateTime, DateTimeOffset, TimeSpan
  • KeyValuePair<,> - как противоположность, DictionaryEntry не является неизменным
  • Tuple<...>
  • (Multicast)Delegate- подобно строкам, всегда возвращается новый экземпляр при его изменении.
  • Guid
  • Version

Интересно, string на самом деле не является действительно неизменным; однако мы можем рассматривать его как «практически неизменный» тип, а это означает, что содержимое экземпляра строки не может быть изменено общедоступными способами (по крайней мере, в безопасном контексте). Но это, например, wstrcpy внутренний метод, который используется StringBuilder класса для управления экземпляром строки.


0