Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- В c# существуют примитивные типы(такие как Int32,Double...), поскольку примитивные типы - самые частоиспользуемые в языке, то для них существуют псевдонимы (int,double). Это Value типы которые хранятся в стеке
- В C# существуют проблемы связанные с тем, что есть возможность переполнения типа, например:
- ```csharp
- int s = int.MaxValue - 1;
- int ss = 2;
- var res = s + ss; // (-int.MaxValue)
- ```
- Т.е переполнение не генерирует ошибку, а просто складывает при этом закольцовывая результат
- Для того чтобы при переполнении генерировалась ошибка можно глобально поставить это используя флаг компиляции /checked+
- Либо используя checked:
- Вот так будет сгенерирован OverflowException
- ```csharp
- int s = int.MaxValue - 1;
- int ss = 2;
- checked
- {
- _res = s + ss;
- }
- ```
- Размещение кода в блоке checked говорит компилятору, генерировать IL код с другими инструкциями, например если при сложении двух чисел раньше генерировалась инструкция add, то, теперь будет генерироваться инструкция add.ovf
- Кстати, вот так ошибка генерироваться не будет, инструкция не работает для вложенных методов, только для инлайн кода:
- ```csharp
- int s = int.MaxValue - 1;
- int ss = 2;
- checked
- {
- AddMethod(s, ss);
- }
- ```
- Также существует ключевое слово unchecked, используется если стоит флажок /checked+ при компиляции, чтобы отключить ошибку при переполнении
- Особо примечательно, что тип Decimal игнорирует все правила и всегда при переполнии генерирует System.OverflowException: Value was either too large or too small for a Decimal:
- Использование флага checked немного замедляет работу программы
- ```csharp
- decimal s = decimal.MaxValue - 1;
- decimal ss = 2;
- decimal res = s + ss;
- Console.WriteLine(_res);
- ```
- # Ссылочные и значимые типы
- Все типы в CLR разделяются на значимые и ссылочные, ссылоные типы - классы хранятся в куче, а указатель на них - в стеке.
- Таким образом память если нужно сослаться на один и тот же ссылочный объект из нескольких мест в программе, то будет создан указатель на этот участок кучи, это очень похоже на классы entity у Мартина Фаулера, их идентичность - адрес в куче.
- Структуры размещаются в стеке, и если экземпляр структуры возвращается их метода, то в стеке создается новая структура, т.е выделяется память для хранения того же объекта, который уже был создан в методе и происходит копирование полей в область памяти выделенную вызывающим методом, таким образом возвращение структуры из метода - оверхед, также если приходится создавать массив одинаковых объектов-структур это также сказывается на памяти. Замечу, что речь идет именно о неупакованных структурах
- Все структуры наследуются от System.ValueType, который в свою очередь наследуется от System.Object переопределяя Equals и GetHashCode, Equals переопределяется так, что при сравнении двух структур сравниваются значения их полей,а не ссылки, в случае GetHashCode - вычисляется хеш по всем полям структуры, в отличии от хеша адреса в куче(у ссылочных типов)
- Иногда стоит предпочитать структуры классам, например, когда нужно структурное сравнение объектов, но необходимо помнить, что в таком случае в стеке будут храниться все созданные экземпляры.Мартин Фаулер называет подобные объекты - record'ами
- Также сразу при объявлении структуры происходит ее инициализация(хотя компилятор и не дает обращаться к полям не проинициализированной ключевым словом new структуры), поэтому не может возникнуть NRE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement