День сто сорок восьмой. #ВопросыНаСобеседовании
Самые часто задаваемые вопросы на собеседовании по .NET
2. Что такое CLR?
CLR (Common Language Runtime) – Общеязыковая Среда Исполнения. Она работает как слой между операционной системой и приложениями, написанными на языках .Net, которые соответствуют Общеязыковой Спецификации (CLS). Основной функцией CLR является преобразование управляемого кода в машинный код и последующее выполнение программы. Управляемый код компилируется только тогда, когда это необходимо, то есть он преобразует соответствующие инструкции при вызове каждой функции. Компиляция JIT позволяет преобразовать промежуточный язык (MSIL) в машинный код по требованию во время выполнения приложения.
Во время выполнения приложения .Net управление переходит к операционной системе, она создает процесс для загрузки CLR. Программа, используемая операционной системой для загрузки CLR, называется средой выполнения, которая отличается в зависимости от типа приложения: настольное, веб-приложение и т.д.
Среда выполнения CLR имеет набор сервисов:
1. Распознаватель Сборок (Assembly Resolver)
Читает манифест приложения, определяет приватную или общую сборку, необходимую для выполнения приложения и передаёт запрос загрузчику сборок.
2. Загрузчик Сборок (Assembly Loader)
Загружает сборку в процесс приложения на основе инструкций распознавателя сборок.
3. Инспектор Типов (Type Checker)
Проверяет типы, используемые в приложении, на соответствие со стандартами CTS или CLS, поддерживаемыми CLR, что обеспечивает безопасность типов.
4. Маршаллер COM (COM marshaller)
Обеспечивает связь с COM-компонентами.
5. Диспетчер Отладки (Debug Manager)
Активирует утилиту отладчика для поддержки построчного выполнения. Разработчик может вносить изменения, не прерывая отладки приложения.
6. Поддержка Потоков (Thread Support)
Управляет потоками выполнения в процессе приложения.
7. IL Компилятор (IL to Native compiler)
Компилятор IL в машинный язык называется JIT-компилятором (Just-In-Time). Он преобразует IL-код в машинный код операционной системы во время выполнения.
8. Менеджер Исключений (Exception Manager)
Обрабатывает исключения, генерируемые приложением, выполняя блоки catch, либо при отсутствии обработчика завершает работу приложения.
9. Сборщик Мусора (Garbage Collector)
Освобождает память от неиспользуемых объектов, это обеспечивает автоматическое управление памятью.
Источник: https://www.c-sharpcorner.com
Самые часто задаваемые вопросы на собеседовании по .NET
2. Что такое CLR?
CLR (Common Language Runtime) – Общеязыковая Среда Исполнения. Она работает как слой между операционной системой и приложениями, написанными на языках .Net, которые соответствуют Общеязыковой Спецификации (CLS). Основной функцией CLR является преобразование управляемого кода в машинный код и последующее выполнение программы. Управляемый код компилируется только тогда, когда это необходимо, то есть он преобразует соответствующие инструкции при вызове каждой функции. Компиляция JIT позволяет преобразовать промежуточный язык (MSIL) в машинный код по требованию во время выполнения приложения.
Во время выполнения приложения .Net управление переходит к операционной системе, она создает процесс для загрузки CLR. Программа, используемая операционной системой для загрузки CLR, называется средой выполнения, которая отличается в зависимости от типа приложения: настольное, веб-приложение и т.д.
Среда выполнения CLR имеет набор сервисов:
1. Распознаватель Сборок (Assembly Resolver)
Читает манифест приложения, определяет приватную или общую сборку, необходимую для выполнения приложения и передаёт запрос загрузчику сборок.
2. Загрузчик Сборок (Assembly Loader)
Загружает сборку в процесс приложения на основе инструкций распознавателя сборок.
3. Инспектор Типов (Type Checker)
Проверяет типы, используемые в приложении, на соответствие со стандартами CTS или CLS, поддерживаемыми CLR, что обеспечивает безопасность типов.
4. Маршаллер COM (COM marshaller)
Обеспечивает связь с COM-компонентами.
5. Диспетчер Отладки (Debug Manager)
Активирует утилиту отладчика для поддержки построчного выполнения. Разработчик может вносить изменения, не прерывая отладки приложения.
6. Поддержка Потоков (Thread Support)
Управляет потоками выполнения в процессе приложения.
7. IL Компилятор (IL to Native compiler)
Компилятор IL в машинный язык называется JIT-компилятором (Just-In-Time). Он преобразует IL-код в машинный код операционной системы во время выполнения.
8. Менеджер Исключений (Exception Manager)
Обрабатывает исключения, генерируемые приложением, выполняя блоки catch, либо при отсутствии обработчика завершает работу приложения.
9. Сборщик Мусора (Garbage Collector)
Освобождает память от неиспользуемых объектов, это обеспечивает автоматическое управление памятью.
Источник: https://www.c-sharpcorner.com
👍1
День сто сорок девятый. #ЗаметкиНаПолях
Отражение. Начало
Отражение предоставляет объекты (типа
Вот простой пример отражения с использованием статического метода
- Получение доступа к атрибутам в метаданных программы.
- Изучение и создание экземпляров типов в сборке.
- Создание новых типов во время выполнения. Используются классы из
- Позднее связывание, доступ к методам типов, созданных во время выполнения.
Продолжение следует…
Источник: https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/concepts/reflection
Отражение. Начало
Отражение предоставляет объекты (типа
Type
), которые описывают сборки, модули и типы. Используется для динамического создания экземпляра типа, привязки типа к существующему объекту или получения типа из существующего объекта и вызова его методов или доступа к его полям и свойствам. Если вы используете атрибуты в своем коде, отражение позволяет вам получить к ним доступ. Вот простой пример отражения с использованием статического метода
GetType
, унаследованного всеми типами из базового класса Object
, для получения типа переменной:// Получение информации о типеСценарии использования:
int i = 42;
System.Type type = i.GetType();
System.Console.WriteLine(type);
// Вывод: System.Int32
// Получение информации о сборке
System.Reflection.Assembly info = typeof(System.Int32).Assembly;
System.Console.WriteLine(info);
// Вывод:
// mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- Получение доступа к атрибутам в метаданных программы.
- Изучение и создание экземпляров типов в сборке.
- Создание новых типов во время выполнения. Используются классы из
System.Reflection.Emit
.- Позднее связывание, доступ к методам типов, созданных во время выполнения.
Продолжение следует…
Источник: https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/concepts/reflection
День сто пятидесятый. #ЗаметкиНаПолях
Отражение. Продолжение
Наряду с
Классы System.Reflection:
1. Assembly - распознавание и загрузка сборки, загрузка модулей из манифеста сборки, поиск типа в этой сборке и создание его экземпляров.
2. Module - обнаружение информации, такой как сборка, содержащая модуль и классы в модуле, получение всех глобальных и неглобальные методов, определенных в модуле.
3. ConstructorInfo - обнаружение имени, параметров, модификаторов доступа и подробностей реализации конструктора. Методы GetConstructors и GetConstructor используются для вызова определенного конструктора.
4. MethodInfo - обнаружение имени, типа возвращаемого значения, параметров, модификаторов доступа и подробностей реализации метода. Методы GetMethods и GetMethod используются для вызова определенного метода.
5. FieldInfo – обнаружение имени, модификаторов доступа и подробностей реализации поля, а также для получения или установки значений поля.
6. EventInfo – обнаружение имени, типа данных обработчика событий, пользовательских атрибутов, и т.п. события, а также для добавления или удаления обработчиков событий.
7. PropertyInfo - обнаружение имени, типа данных и состояния свойства, а также для получения или установки значений свойства.
8. ParameterInfo - обнаружение имени параметра, типа данных, является ли параметр входным или выходным, а также положения параметра в сигнатуре метода.
9. CustomAttributeData - обнаружение информации о пользовательских атрибутах, позволяет исследовать атрибуты, не создавая их экземпляры.
Отражение также можно использовать для создания приложений, называемых браузерами типов, которые позволяют пользователям выбирать типы, а затем просматривать информацию об этих типах.
Продолжение следует…
Источник: https://docs.microsoft.com/ru-ru/dotnet/framework/reflection-and-codedom/reflection
Отражение. Продолжение
Наряду с
System.Type
, классы в пространстве имен System.Reflection
позволяют получать информацию о загруженных сборках и определенных в них типах, таких как классы, интерфейсы и структуры. Сборки содержат модули, модули содержат типы, а типы содержат члены. Отражения предоставляет объекты, которые инкапсулируют сборки, модули и типы. Вы можете использовать отражение, чтобы динамически создавать экземпляр типа, связывать тип с существующим объектом или получать тип существующего объекта. Затем вы можете вызвать методы типа или получить доступ к его полям и свойствам.Классы System.Reflection:
1. Assembly - распознавание и загрузка сборки, загрузка модулей из манифеста сборки, поиск типа в этой сборке и создание его экземпляров.
2. Module - обнаружение информации, такой как сборка, содержащая модуль и классы в модуле, получение всех глобальных и неглобальные методов, определенных в модуле.
3. ConstructorInfo - обнаружение имени, параметров, модификаторов доступа и подробностей реализации конструктора. Методы GetConstructors и GetConstructor используются для вызова определенного конструктора.
4. MethodInfo - обнаружение имени, типа возвращаемого значения, параметров, модификаторов доступа и подробностей реализации метода. Методы GetMethods и GetMethod используются для вызова определенного метода.
5. FieldInfo – обнаружение имени, модификаторов доступа и подробностей реализации поля, а также для получения или установки значений поля.
6. EventInfo – обнаружение имени, типа данных обработчика событий, пользовательских атрибутов, и т.п. события, а также для добавления или удаления обработчиков событий.
7. PropertyInfo - обнаружение имени, типа данных и состояния свойства, а также для получения или установки значений свойства.
8. ParameterInfo - обнаружение имени параметра, типа данных, является ли параметр входным или выходным, а также положения параметра в сигнатуре метода.
9. CustomAttributeData - обнаружение информации о пользовательских атрибутах, позволяет исследовать атрибуты, не создавая их экземпляры.
Отражение также можно использовать для создания приложений, называемых браузерами типов, которые позволяют пользователям выбирать типы, а затем просматривать информацию об этих типах.
Продолжение следует…
Источник: https://docs.microsoft.com/ru-ru/dotnet/framework/reflection-and-codedom/reflection
День сто пятьдесят первый. #ЗаметкиНаПолях
Отражение. Окончание
Небольшое приложение для демонстрации возможностей отражения. А заодно протестировать Git в Visual Studio и сервис Azure DevOps (о нём позже). Сразу оговорюсь, с Git практически не работал, по работе больше используем SVN, поэтому, возможно, репозиторий не оформлен по всем канонам. Не судите строго.
В общем, небольшая консольная утилита анализирует сборки .Net в файлах, помещаемых в папку files и выводит информацию о сборке, классах в сборке и членах классов. Информация выводится в консоль и в лог-файл в папке logs.
Если анализируемая сборка ссылается на другие сборки, то необходимые сборки должны быть помещены в папку libs.
Исходный код: https://dev.azure.com/sbenzenko/NetDeveloper/_git/Reflection
Пожалуйста, не стесняйтесь использовать и изменять код, присылать замечания и предложения.
Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 23.
Отражение. Окончание
Небольшое приложение для демонстрации возможностей отражения. А заодно протестировать Git в Visual Studio и сервис Azure DevOps (о нём позже). Сразу оговорюсь, с Git практически не работал, по работе больше используем SVN, поэтому, возможно, репозиторий не оформлен по всем канонам. Не судите строго.
В общем, небольшая консольная утилита анализирует сборки .Net в файлах, помещаемых в папку files и выводит информацию о сборке, классах в сборке и членах классов. Информация выводится в консоль и в лог-файл в папке logs.
Если анализируемая сборка ссылается на другие сборки, то необходимые сборки должны быть помещены в папку libs.
Исходный код: https://dev.azure.com/sbenzenko/NetDeveloper/_git/Reflection
Пожалуйста, не стесняйтесь использовать и изменять код, присылать замечания и предложения.
Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 23.
День сто пятьдесят второй. #МоиИнструменты
Azure DevOps
Этот пост серии Мои Инструменты будет отличаться от остальных, поскольку этим инструментом я только начал пользоваться. То есть, не могу в полной мере назвать его своим. Как обещал, рассказываю про Microsoft Azure DevOps. Его можно найти здесь https://visualstudio.microsoft.com/ru/team-services/
Как видно из ссылки, это сервис больше для командной разработки. Но и индивидуальные разработчики могут найти много полезного. Во-первых, это бесплатный репозиторий Git. Можно создавать как публичные, так и приватные репозитории.
Система создана для управления вашими проектами. Создаёте проект, система сразу же создаёт для него репозиторий, ссылку на который вы можете скопировать, либо (что очень круто) выполнить Git Clone сразу в вашу любимую IDE (Visual Studio, VS Code, PHP Storm, Eclipse, тысячи их…(с)). Соответственно вся информация о репозитории(-ях): Commits, Pushes, Tags и т.п. - тоже доступна на вкладке Repos.
На вкладке Boards доступны различные инструменты управления проектом: Agile, Scrum, вотэтовсё. Можно управлять рабочим процессом, создавать задания, назначать на них исполнителей и отслеживать выполнение. Кроме того, задания можно привязывать к коммитам Git и как в статистике коммитов, так и в статистике заданий, будет отображаться информация о том, какой коммит к какому заданию привязан.
На вкладке Test Plans можно управлять тестированием проекта. Например, указывать группе тестировщиков (или себе на будущее), как надо тестировать тот или иной функционал.
Вкладка Pipelines самая интересная. Позволяет управлять развёртыванием проекта. Например, можно настроить выполнение заданий при каждом коммите: автоматическую сборку проекта, выполнение автоматизированных тестов, выкладывание продакшн кода в облачный сервис и т.п. И если что-то из этого завершится неудачей, вы получите email и это будет отображено в описании проекта. Можно настраивать развёртывание нескольких версий приложения (версии для разработки, стейджинг и продакшн версии) по-разному.
В общем, система очень богатая и полезная. Здесь мы только «поцарапали её поверхность», как говорят у них.
Источник и подробности (на английском): https://www.youtube.com/watch?v=H-R2bCXfz8I
Azure DevOps
Этот пост серии Мои Инструменты будет отличаться от остальных, поскольку этим инструментом я только начал пользоваться. То есть, не могу в полной мере назвать его своим. Как обещал, рассказываю про Microsoft Azure DevOps. Его можно найти здесь https://visualstudio.microsoft.com/ru/team-services/
Как видно из ссылки, это сервис больше для командной разработки. Но и индивидуальные разработчики могут найти много полезного. Во-первых, это бесплатный репозиторий Git. Можно создавать как публичные, так и приватные репозитории.
Система создана для управления вашими проектами. Создаёте проект, система сразу же создаёт для него репозиторий, ссылку на который вы можете скопировать, либо (что очень круто) выполнить Git Clone сразу в вашу любимую IDE (Visual Studio, VS Code, PHP Storm, Eclipse, тысячи их…(с)). Соответственно вся информация о репозитории(-ях): Commits, Pushes, Tags и т.п. - тоже доступна на вкладке Repos.
На вкладке Boards доступны различные инструменты управления проектом: Agile, Scrum, вотэтовсё. Можно управлять рабочим процессом, создавать задания, назначать на них исполнителей и отслеживать выполнение. Кроме того, задания можно привязывать к коммитам Git и как в статистике коммитов, так и в статистике заданий, будет отображаться информация о том, какой коммит к какому заданию привязан.
На вкладке Test Plans можно управлять тестированием проекта. Например, указывать группе тестировщиков (или себе на будущее), как надо тестировать тот или иной функционал.
Вкладка Pipelines самая интересная. Позволяет управлять развёртыванием проекта. Например, можно настроить выполнение заданий при каждом коммите: автоматическую сборку проекта, выполнение автоматизированных тестов, выкладывание продакшн кода в облачный сервис и т.п. И если что-то из этого завершится неудачей, вы получите email и это будет отображено в описании проекта. Можно настраивать развёртывание нескольких версий приложения (версии для разработки, стейджинг и продакшн версии) по-разному.
В общем, система очень богатая и полезная. Здесь мы только «поцарапали её поверхность», как говорят у них.
Источник и подробности (на английском): https://www.youtube.com/watch?v=H-R2bCXfz8I
День сто пятьдесят третий. #ЗаметкиНаПолях
Решатель судоку
По мотивам давнишнего поста https://t.iss.one/NetDeveloperDiary/83 решил сделать небольшую библиотеку для решения судоку на C#. Код здесь: https://dev.azure.com/sbenzenko/NetDeveloper/_git/SudokuSolver
Краткое описание
Сетка судоку представляет собой двумерный массив типа
Решение задачи (метод SolveSudoku):
1) В методе
2) В цикле пробуем записать в клетку цифры от 1 до 9. В методе
- нет одинаковых цифр в текущем секторе 3х3
- нет одинаковых цифр в текущем столбце
- нет одинаковых цифр в текущей строке
3) Если правила не нарушены, рекурсивно вызываем
Если
В противном случае нужно отменить сделанные изменения:
- устанавливаем значение клетки обратно в
- увеличиваем количество «отмен» в переменной
4) Если мы прошли по циклу в п.2 и ни одно число не подошло, возвращаем
В тестовом проекте (
Примечания:
- Пока нет визуального UI, возможно сделаю позже.
- Решение можно оптимизировать: выполнять поиск доступных цифр в п.2.
Источник и подробности с решением на Python (на английском языке): https://www.youtube.com/watch?v=auK3PSZoidc
Решатель судоку
По мотивам давнишнего поста https://t.iss.one/NetDeveloperDiary/83 решил сделать небольшую библиотеку для решения судоку на C#. Код здесь: https://dev.azure.com/sbenzenko/NetDeveloper/_git/SudokuSolver
Краткое описание
Сетка судоку представляет собой двумерный массив типа
byte
. Первоначально заполняется цифрами из задачи судоку, свободные клетки нулями.Решение задачи (метод SolveSudoku):
1) В методе
FindNextCellToFill
находим следующую свободную клетку (со значением 0). Если метод возвращает -1, значит свободных клеток нет, задача решена.2) В цикле пробуем записать в клетку цифры от 1 до 9. В методе
IsValid
проверяем, не нарушает ли новая цифра правила:- нет одинаковых цифр в текущем секторе 3х3
- нет одинаковых цифр в текущем столбце
- нет одинаковых цифр в текущей строке
3) Если правила не нарушены, рекурсивно вызываем
SolveSudoku
(которая выполняет процедуру для следующей пустой клетки). Если
SolveSudoku
вернёт true
, значит сетка заполнена и задача решена (см. п.1). Выходим из процедуры.В противном случае нужно отменить сделанные изменения:
- устанавливаем значение клетки обратно в
0
,- увеличиваем количество «отмен» в переменной
BackTracks
(для статистики).4) Если мы прошли по циклу в п.2 и ни одно число не подошло, возвращаем
false
, т.е. решений задачи нет.В тестовом проекте (
SudokuSolverTests
) есть три примера решений судоку (лёгкого, среднего и «самого сложного известного»). Они же записаны в консольном проекте SolveSudokuConsole
от простого к сложному. Можете раскомментировать один из них и посмотреть решение. По количеству выводимых «отмен» (Backtracks
) очевидна сложность задачи.Примечания:
- Пока нет визуального UI, возможно сделаю позже.
- Решение можно оптимизировать: выполнять поиск доступных цифр в п.2.
Источник и подробности с решением на Python (на английском языке): https://www.youtube.com/watch?v=auK3PSZoidc
День сто пятьдесят четвёртый. #ЗаметкиНаПолях
Сериализация. Начало
Сериализация - это процесс преобразования объекта в поток байтов для хранения его в памяти, базе данных или файле. Основная цель - сохранить состояние объекта, чтобы иметь возможность воссоздать его при необходимости. Обратный процесс называется десериализацией.
Объект сериализуется в поток, который переносит не только данные, но и информацию о типе объекта, например его версию, имя сборки и языковые стандарты. Из этого потока он может быть сохранен в базе данных, файле или памяти.
Примеры использования:
- отправка объекта в удаленное приложение с помощью веб-службы,
- передача объекта из одного домена в другой,
- передача объекта через брандмауэр в виде строки XML,
- поддержание безопасности при передаче пользовательских данных между приложениями,
- сохранение набора объектов (например, состояние приложения) в качестве «резервной копии»,
- глубокое копирование объектов (об этом позже).
Чтобы сериализовать объект, вам нужен сериализуемый объект, поток, содержащий сериализованный объект, и средство форматирования.
Примените атрибут
Если сериализованный класс содержит ссылки на объекты других классов, помеченные атрибутом
Пример
Метод
Продолжение следует…
Источники:
- Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 24.
- https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/concepts/serialization/
Сериализация. Начало
Сериализация - это процесс преобразования объекта в поток байтов для хранения его в памяти, базе данных или файле. Основная цель - сохранить состояние объекта, чтобы иметь возможность воссоздать его при необходимости. Обратный процесс называется десериализацией.
Объект сериализуется в поток, который переносит не только данные, но и информацию о типе объекта, например его версию, имя сборки и языковые стандарты. Из этого потока он может быть сохранен в базе данных, файле или памяти.
Примеры использования:
- отправка объекта в удаленное приложение с помощью веб-службы,
- передача объекта из одного домена в другой,
- передача объекта через брандмауэр в виде строки XML,
- поддержание безопасности при передаче пользовательских данных между приложениями,
- сохранение набора объектов (например, состояние приложения) в качестве «резервной копии»,
- глубокое копирование объектов (об этом позже).
Чтобы сериализовать объект, вам нужен сериализуемый объект, поток, содержащий сериализованный объект, и средство форматирования.
System.Runtime.Serialization
содержит классы, необходимые для сериализации и десериализации объектов.Примените атрибут
Serializable
к типу, чтобы указать, что экземпляры этого типа могут быть сериализованы. При попытке сериализовать объект, не помеченный атрибутом Serializable
, выбрасывается исключение. Атрибут Serializable не наследуется производными типами.Если сериализованный класс содержит ссылки на объекты других классов, помеченные атрибутом
Serializable
, эти объекты также будут сериализованы.Пример
public static void Main()Метод
{
var objects = new List<string> { "Jeff", "Kristin", "Grant" };
var stream = SerializeToMemory(objects);
stream.Position = 0;
var deserialized = (List<string>)DeserializeFromMemory(stream);
foreach (var s in deserialized)
Console.WriteLine(s);
}
private static Stream SerializeToMemory(object objects)
{
var stream = new MemoryStream();
new BinaryFormatter().Serialize(stream, objects);
return stream;
}
private static object DeserializeFromMemory(Stream stream)
{
return new BinaryFormatter().Deserialize(stream);
}
SerializeToMemory
создаёт объект System.IO.MemoryStream
, чтобы разместить поток сериализованных данных в памяти. Затем используется объект BinaryFormatter
из пространства имён System.Runtime.Serialization.Formatters.Binary
. Этот объект, реализующий интерфейс IFormatter, «умеет» сериализовывать объекты в поток байтов и десериализовывать их из него.Метод
DeserializeFromMemory
использует тот же поток данных из памяти, чтобы выполнить обратные действия.Продолжение следует…
Источники:
- Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 24.
- https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/concepts/serialization/
День сто пятьдесят пятый. #ЗаметкиНаПолях
Сериализация. Продолжение
Управление сериализацией и десериализацией
После назначения типу атрибута
- поле содержит информацию, становящуюся недействительной после десериализации (указатель, дескриптор или некоторую другую структуру данных, специфичную для конкретной среды);
- поле содержит легко обновляемую информацию (которую легко восстановить без десериализации).
Для восстановления такой информации, а также, если необходимо выполнить какие-либо другие действия при сериализации/десериализации, в типе можно определить методы, помеченные атрибутами
StreamingContext
Это структура, имеющая два открытых свойства только для чтения.
1. Context – ссылка на объект типа
2. State – набор битовых флагов, указывающих источник или приёмник сериализуемых/десериализуемых данных:
- CrossProcess – другой процесс на той же машине;
- CrossMachines – источник/приёмник - другая машина;
- File – источник/приёмник – файл (десериализовать, возможно, будет другой процесс);
- Persistence - источник/приёмник – база данных;
- Remoting – данные являются удалёнными по отношению к текущему контексту;
- Other - источник/приёмник неизвестны;
- Clone – точное копирование объекта (об этом далее);
- CrossAppDomain - источник/приёмник – другой домен приложений;
- All - источник/приёмник – любой контекст (по умолчанию).
Окончание следует…
Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 24.
Сериализация. Продолжение
Управление сериализацией и десериализацией
После назначения типу атрибута
Serializable
все экземпляры его полей (открытые, закрытые, защищённые и т.п.) становятся сериализуемыми. Но можно указать некоторые поля, не подлежащие сериализации с помощью атрибута NonSerialized
. Это делается, например, в следующих случаях:- поле содержит информацию, становящуюся недействительной после десериализации (указатель, дескриптор или некоторую другую структуру данных, специфичную для конкретной среды);
- поле содержит легко обновляемую информацию (которую легко восстановить без десериализации).
Для восстановления такой информации, а также, если необходимо выполнить какие-либо другие действия при сериализации/десериализации, в типе можно определить методы, помеченные атрибутами
OnSerializing
, OnSerialized
, OnDeserializing
, OnDeserialized
:[OnDeserialized]Если после сериализации к типу было добавлено поле, десериализация экземпляра выбросит исключение. В этом случае к новому полю можно добавить атрибут
private void OnDeserialized(StreamingContext context) { … }
OptionalField
. Тогда при десериализации в случае отсутствия данных для этого поля исключения выброшено не будет.StreamingContext
Это структура, имеющая два открытых свойства только для чтения.
1. Context – ссылка на объект типа
object
, содержащий нужный пользователю контекст (используется при переопределении объектов форматирования, реализующих IFormatter
).2. State – набор битовых флагов, указывающих источник или приёмник сериализуемых/десериализуемых данных:
- CrossProcess – другой процесс на той же машине;
- CrossMachines – источник/приёмник - другая машина;
- File – источник/приёмник – файл (десериализовать, возможно, будет другой процесс);
- Persistence - источник/приёмник – база данных;
- Remoting – данные являются удалёнными по отношению к текущему контексту;
- Other - источник/приёмник неизвестны;
- Clone – точное копирование объекта (об этом далее);
- CrossAppDomain - источник/приёмник – другой домен приложений;
- All - источник/приёмник – любой контекст (по умолчанию).
Окончание следует…
Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 24.
День сто пятьдесят шестой. #ЗаметкиНаПолях
Сериализация. Окончание
Пример использования для глубокого копирования
При создании копии объекта возникает проблема с тем, что создаётся поверхностная копия. Даже метод
Одним из способов решить эту проблему, то есть создать глубокую копию объекта, будет использование сериализации. Следующий класс создаёт метод-расширение для глубокого копирования объектов через сериализацию. Замечания:
- объекты копирования должны быть помечены атрибутом
- мы используем упомянутый выше класс
Рассмотрим пример использования этого метода расширения. Допустим, у нас есть простой класс:
Сериализация. Окончание
Пример использования для глубокого копирования
При создании копии объекта возникает проблема с тем, что создаётся поверхностная копия. Даже метод
MemberwiseClone
в System.Object
создает поверхностную копию нового объекта. Копирование объекта выполняется свойство за свойством, если свойство является значимым типом, то копируются данные по битам, а если свойство является ссылочным типом, то копируется ссылка на исходный объект. Другими словами, поле или свойство объекта-клона будет ссылаться на тот же объект.Одним из способов решить эту проблему, то есть создать глубокую копию объекта, будет использование сериализации. Следующий класс создаёт метод-расширение для глубокого копирования объектов через сериализацию. Замечания:
- объекты копирования должны быть помечены атрибутом
Serializable
;- мы используем упомянутый выше класс
StreamingContext
, задавая его свойству State значение StreamingContextStates.Clone
(то есть мы сериализуем объект с целью его копирования).public static class ObjectExtension
{
public static T DeepCopy<T>(this T objSource)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
formatter.Serialize(stream, objSource);
stream.Position = 0;
return (T)formatter.Deserialize(stream);
}
}
}
Рассмотрим пример использования этого метода расширения. Допустим, у нас есть простой класс:
[Serializable]В примере ниже мы составляем список объектов этого класса. Затем делаем поверхностную копию этого списка, а затем глубокую копию. Отличие в том, что, если изменить значение свойства одного из объектов, то изменение затронет как изначальный список, так и его поверхностную копию. А вот глубокая копия останется неизменной:
private class Person
{
public string Name { get; set; }
}
var jeff = new Person { Name = "Jeff" };Если вывести в консоль значения свойств Name объектов из каждого списка, мы получим:
var kris = new Person { Name = "Kristin" };
// изначальный список
var persons = new List<Person> { jeff, kris };
// поверхностная копия
var shallowCopy = new List<Person>(persons);
// глубокая копия
var deepCopy = objects.DeepCopy();
// изменяем свойство объекта
jeff.Name = "Bob";
persons: Bob, KristinИсточник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 24.
shallowCopy: Bob, Kristin
deepCopy: Jeff, Kristin
День сто пятьдесят седьмой. #Оффтоп
Рефакторинг унаследованного (легаси) кода.
Как обычно, гуляя по ютубу, наткнулся на вот такое интересное видео https://www.youtube.com/watch?v=XejfFBvODxc
Лекция разработчика из Додо Пиццы (ВНЕЗАПНО!) по рефакторингу. Как исправлять, поддерживать и покрывать тестами код, при этом сохраняя старый код и не рискуя ничего поломать. Далеко не со всеми методами лично я согласен, однако, есть и некоторые интересные приёмчики.
Коротко об основных приёмах:
1. Сохраняем сигнатуры
Даже самые ужасные на вид сигнатуры из легаси методов безопаснее просто скопировать для использования в новых методах, чем производить какие-либо манипуляции с аргументами.
2. Метод/класс росток
Если нужно внести дополнение в старый метод, вставляем туда новый метод, который покрываем тестами. Хотя бы новый код будет протестирован.
3. Метод/класс обёртка
Для добавления функциональности к старому методу создаём новый метод, в котором вызываем старый и добавляем новый код. В отношении классов используем шаблон Декоратор: наследуем от старого класса, добавляя функциональность.
4. Извлечение и переопределение
Если метод использует функциональность, которую нельзя или трудно протестировать явно (запись в консоль/файл/БД, отправка писем клиентам, отправка платежей и т.п.), извлекаем вызов каждого такого метода в новый метод, который делаем
Рефакторинг унаследованного (легаси) кода.
Как обычно, гуляя по ютубу, наткнулся на вот такое интересное видео https://www.youtube.com/watch?v=XejfFBvODxc
Лекция разработчика из Додо Пиццы (ВНЕЗАПНО!) по рефакторингу. Как исправлять, поддерживать и покрывать тестами код, при этом сохраняя старый код и не рискуя ничего поломать. Далеко не со всеми методами лично я согласен, однако, есть и некоторые интересные приёмчики.
Коротко об основных приёмах:
1. Сохраняем сигнатуры
Даже самые ужасные на вид сигнатуры из легаси методов безопаснее просто скопировать для использования в новых методах, чем производить какие-либо манипуляции с аргументами.
2. Метод/класс росток
Если нужно внести дополнение в старый метод, вставляем туда новый метод, который покрываем тестами. Хотя бы новый код будет протестирован.
3. Метод/класс обёртка
Для добавления функциональности к старому методу создаём новый метод, в котором вызываем старый и добавляем новый код. В отношении классов используем шаблон Декоратор: наследуем от старого класса, добавляя функциональность.
4. Извлечение и переопределение
Если метод использует функциональность, которую нельзя или трудно протестировать явно (запись в консоль/файл/БД, отправка писем клиентам, отправка платежей и т.п.), извлекаем вызов каждого такого метода в новый метод, который делаем
protected virtual
. Далее создаём тестовый класс, унаследованный от старого класса, в котором переопределяем нужные методы, чтобы их можно было протестировать (например, вместо записи в файл сохраняем в память). Таким образом можно протестировать логику старого класса через тестовый, не вызывая ненужных нам методов.День сто пятьдесят восьмой. #ВопросыНаСобеседовании
Самые часто задаваемые вопросы на собеседовании по .NET
3. Что такое Общая Система Типов (CTS)?
Общая система типов определяет, как типы объявляются, используются и управляются в общеязыковой среде выполнения (CLR), а также является важной частью поддержки межъязыковой интеграции во время выполнения. CTS выполняет следующие функции:
1. Создает структуру, которая помогает обеспечить межъязыковую интеграцию, безопасность типов и высокопроизводительное выполнение кода.
2. Предоставляет объектно-ориентированную модель, которая поддерживает полную реализацию многих языков программирования.
3. Определяет правила, которым должны следовать языки, что помогает обеспечить взаимодействие объектов, написанных на разных языках.
4. Предоставляет библиотеку, которая содержит примитивные типы данных (такие как Boolean, Byte, Char, Int32 и UInt64), используемые при разработке приложений.
Типы в .NET
Все типы в .NET делятся на значимые и ссылочные.
Значимые типы - это типы данных, объекты которых представлены фактическим значением объекта. Если экземпляр значимого типа присвоен переменной, этой переменной даётся свежая копия значения.
Ссылочные типы - это типы данных, объекты которых представлены ссылкой (аналогично указателю) на фактическое значение объекта. Если ссылочный тип присвоен переменной, эта переменная ссылается (указывает) на исходное значение. Копия значения не делается.
Категории типов:
- Классы
- Структуры
- Перечисления
- Интерфейсы
- Делегаты
Определения типов
Определение типа включает в себя:
- Любые атрибуты, определенные для типа
- Доступность (видимость) типа
- Имя типа
- Базовый тип типа
- Любые интерфейсы, реализуемые типом
- Определения для каждого из членов типа
Члены Типа
Среда выполнения позволяет вам определять элементы вашего типа, которые определяют поведение и состояние типа:
- Поля
- Свойства
- Методы
- Конструкторы
- События
- Вложенные типы
Источник: https://docs.microsoft.com/en-us/dotnet/standard/base-types/common-type-system
Самые часто задаваемые вопросы на собеседовании по .NET
3. Что такое Общая Система Типов (CTS)?
Общая система типов определяет, как типы объявляются, используются и управляются в общеязыковой среде выполнения (CLR), а также является важной частью поддержки межъязыковой интеграции во время выполнения. CTS выполняет следующие функции:
1. Создает структуру, которая помогает обеспечить межъязыковую интеграцию, безопасность типов и высокопроизводительное выполнение кода.
2. Предоставляет объектно-ориентированную модель, которая поддерживает полную реализацию многих языков программирования.
3. Определяет правила, которым должны следовать языки, что помогает обеспечить взаимодействие объектов, написанных на разных языках.
4. Предоставляет библиотеку, которая содержит примитивные типы данных (такие как Boolean, Byte, Char, Int32 и UInt64), используемые при разработке приложений.
Типы в .NET
Все типы в .NET делятся на значимые и ссылочные.
Значимые типы - это типы данных, объекты которых представлены фактическим значением объекта. Если экземпляр значимого типа присвоен переменной, этой переменной даётся свежая копия значения.
Ссылочные типы - это типы данных, объекты которых представлены ссылкой (аналогично указателю) на фактическое значение объекта. Если ссылочный тип присвоен переменной, эта переменная ссылается (указывает) на исходное значение. Копия значения не делается.
Категории типов:
- Классы
- Структуры
- Перечисления
- Интерфейсы
- Делегаты
Определения типов
Определение типа включает в себя:
- Любые атрибуты, определенные для типа
- Доступность (видимость) типа
- Имя типа
- Базовый тип типа
- Любые интерфейсы, реализуемые типом
- Определения для каждого из членов типа
Члены Типа
Среда выполнения позволяет вам определять элементы вашего типа, которые определяют поведение и состояние типа:
- Поля
- Свойства
- Методы
- Конструкторы
- События
- Вложенные типы
Источник: https://docs.microsoft.com/en-us/dotnet/standard/base-types/common-type-system
День сто пятьдесят девятый. #ВопросыНаСобеседовании
Самые часто задаваемые вопросы на собеседовании по .NET
4. Что такое Общеязыковая Спецификация (CLS)?
.NET Framework не зависит от языка. Это означает, что как разработчик вы можете писать на одном из множества языков, поддерживаемых .NET Framework, таких как C#, C++/CLI, Eiffel, F#, IronPython, IronRuby, PowerBuilder, Visual Basic и т.п. Вы можете получить доступ к типам и членам библиотек классов, разработанных для .NET Framework, не зная языка, на котором они были изначально написаны, и не следуя никаким соглашениям исходного языка. Если вы разработчик компонента, доступ к вашему компоненту может получить любое приложение .NET Framework независимо от его языка.
Чтобы полностью взаимодействовать с другими объектами, написанными на любом языке, объекты должны предоставлять вызывающим их объектам только те функции, которые являются общими для всех языков. Этот общий набор функций определяется Общеязыковой Спецификацией (CLS), которая представляет собой набор правил, применимых к сгенерированным сборкам.
Если ваш компонент соответствует CLS, он гарантированно совместим с ней и доступен из кода в сборках, написанных на любом языке программирования, который поддерживает CLS. Чтобы создать компонент, который не зависит от языка, вам нужно применить правила соответствия CLS только к общедоступному интерфейсу вашего компонента. Ваша приватная реализация не обязана соответствовать спецификации.
Чтобы сообщить компилятору, что ваша сборка должна соответствовать CLS при компиляции, нужно применить атрибут
Самые часто задаваемые вопросы на собеседовании по .NET
4. Что такое Общеязыковая Спецификация (CLS)?
.NET Framework не зависит от языка. Это означает, что как разработчик вы можете писать на одном из множества языков, поддерживаемых .NET Framework, таких как C#, C++/CLI, Eiffel, F#, IronPython, IronRuby, PowerBuilder, Visual Basic и т.п. Вы можете получить доступ к типам и членам библиотек классов, разработанных для .NET Framework, не зная языка, на котором они были изначально написаны, и не следуя никаким соглашениям исходного языка. Если вы разработчик компонента, доступ к вашему компоненту может получить любое приложение .NET Framework независимо от его языка.
Чтобы полностью взаимодействовать с другими объектами, написанными на любом языке, объекты должны предоставлять вызывающим их объектам только те функции, которые являются общими для всех языков. Этот общий набор функций определяется Общеязыковой Спецификацией (CLS), которая представляет собой набор правил, применимых к сгенерированным сборкам.
Если ваш компонент соответствует CLS, он гарантированно совместим с ней и доступен из кода в сборках, написанных на любом языке программирования, который поддерживает CLS. Чтобы создать компонент, который не зависит от языка, вам нужно применить правила соответствия CLS только к общедоступному интерфейсу вашего компонента. Ваша приватная реализация не обязана соответствовать спецификации.
Чтобы сообщить компилятору, что ваша сборка должна соответствовать CLS при компиляции, нужно применить атрибут
CLSCompliant
. Например:using System;Попытка компиляции этого примера отобразит предупреждение компилятора: warning CS3003: Type of 'Person.Age' is not CLS-compliant (Тип 'Person.Age' не совместим с CLS). Вы можете сделать класс
[assembly: CLSCompliant(true)]
public class Person
{
private UInt16 _age = 0;
public UInt16 Age
{ get { return _age; } }
}
Person
совместимым с CLS, изменив тип свойства Age
с UInt16
на Int16
, которое является CLS-совместимым 16-разрядным целым числом со знаком. Вам не нужно менять тип приватного поля _age
:using System;Источник: https://docs.microsoft.com/en-us/dotnet/standard/language-independence-and-language-independent-components
[assembly: CLSCompliant(true)]
public class Person
{
private Int16 _age = 0;
public Int16 Age { get { return _age; } }
}
День сто шестидесятый. #ВопросыНаСобеседовании
Самые часто задаваемые вопросы на собеседовании по .NET
5. Что такое управляемый код?
Управляемый код - это код, выполнение которого управляется средой исполнения. В этом случае рассматриваемая среда исполнения называется Common Language Runtime или CLR, независимо от реализации (Mono или .NET Framework или .NET Core). CLR отвечает за распознавание управляемого кода, компиляцию его в машинный код и последующее выполнение. Кроме того, среда выполнения предоставляет несколько важных сервисов, таких как автоматическое управление памятью, границы безопасности, безопасность типов и т.д.
В этом смысле программы на C/C++ называются «неуправляемым кодом». Здесь программист отвечает практически за всё. Такая программа - это, по сути, двоичный файл, который операционная система загружает в память и исполняет. Всё остальное, от управления памятью до соображений безопасности, является ответственностью программиста.
Управляемый код написан на одном из языков высокого уровня, который можно запускать поверх .NET, таких как C#, Visual Basic, F# и другие. Когда вы компилируете код, написанный на этих языках, с помощью соответствующего компилятора, вы не получаете машинный код. Вы получаете код на промежуточном языке (Intermediate Language), который среда исполнения затем компилирует и выполняет. C++ является единственным исключением из этого правила, поскольку он также может создавать собственные неуправляемые двоичные файлы, которые работают в Windows.
Конечно, CLR позволяет переходить через границы между управляемым и неуправляемым миром, и есть много примеров кода, который делает это, даже в библиотеках базовых классов. Это называется совместимостью (interoperability или interop). Это позволяет вам, например, обернуть неуправляемую библиотеку и обратиться к ней. Однако важно отметить, что при этом, когда код пересекает границы среды выполнения, фактическое управление выполнением снова оказывается в руках неуправляемого кода и, таким образом, попадает под те же ограничения.
Подобно этому, C# позволяет вам использовать неуправляемые конструкции, такие как указатели, непосредственно в коде, используя так называемый небезопасный контекст, который обозначает фрагмент кода, выполнение которого не управляется CLR.
Источник: https://docs.microsoft.com/en-us/dotnet/standard/language-independence-and-language-independent-components
Самые часто задаваемые вопросы на собеседовании по .NET
5. Что такое управляемый код?
Управляемый код - это код, выполнение которого управляется средой исполнения. В этом случае рассматриваемая среда исполнения называется Common Language Runtime или CLR, независимо от реализации (Mono или .NET Framework или .NET Core). CLR отвечает за распознавание управляемого кода, компиляцию его в машинный код и последующее выполнение. Кроме того, среда выполнения предоставляет несколько важных сервисов, таких как автоматическое управление памятью, границы безопасности, безопасность типов и т.д.
В этом смысле программы на C/C++ называются «неуправляемым кодом». Здесь программист отвечает практически за всё. Такая программа - это, по сути, двоичный файл, который операционная система загружает в память и исполняет. Всё остальное, от управления памятью до соображений безопасности, является ответственностью программиста.
Управляемый код написан на одном из языков высокого уровня, который можно запускать поверх .NET, таких как C#, Visual Basic, F# и другие. Когда вы компилируете код, написанный на этих языках, с помощью соответствующего компилятора, вы не получаете машинный код. Вы получаете код на промежуточном языке (Intermediate Language), который среда исполнения затем компилирует и выполняет. C++ является единственным исключением из этого правила, поскольку он также может создавать собственные неуправляемые двоичные файлы, которые работают в Windows.
Конечно, CLR позволяет переходить через границы между управляемым и неуправляемым миром, и есть много примеров кода, который делает это, даже в библиотеках базовых классов. Это называется совместимостью (interoperability или interop). Это позволяет вам, например, обернуть неуправляемую библиотеку и обратиться к ней. Однако важно отметить, что при этом, когда код пересекает границы среды выполнения, фактическое управление выполнением снова оказывается в руках неуправляемого кода и, таким образом, попадает под те же ограничения.
Подобно этому, C# позволяет вам использовать неуправляемые конструкции, такие как указатели, непосредственно в коде, используя так называемый небезопасный контекст, который обозначает фрагмент кода, выполнение которого не управляется CLR.
Источник: https://docs.microsoft.com/en-us/dotnet/standard/language-independence-and-language-independent-components
День сто шестьдесят первый. #TipsAndTricks
28. Советы по отладке в Visual Studio
1. Нажатие F10 для сборки и запуска проекта для отладки (вместо F5) автоматически остановит выполнение на первой строке вашего кода. Не нужны никакие точки останова. (C VS2005)
2. Reattach to process (Shift+Alt+P) очень полезно, когда вам нужно подключаться к одному и тому же процессу снова и снова. (C VS2017 v15.8)
3. Синий кружок с восклицательным знаком на значке точки останова обозначает переключение потоков при проходе по шагам в отладчике (см. картинку). (C VS2013)
Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-tips-and-tricks/
28. Советы по отладке в Visual Studio
1. Нажатие F10 для сборки и запуска проекта для отладки (вместо F5) автоматически остановит выполнение на первой строке вашего кода. Не нужны никакие точки останова. (C VS2005)
2. Reattach to process (Shift+Alt+P) очень полезно, когда вам нужно подключаться к одному и тому же процессу снова и снова. (C VS2017 v15.8)
3. Синий кружок с восклицательным знаком на значке точки останова обозначает переключение потоков при проходе по шагам в отладчике (см. картинку). (C VS2013)
Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-tips-and-tricks/
День сто шестьдесят второй. #TipsAndTricks
29. Редактор Visual Studio
1. Легко оборачивайте элементы HTML в <div>, нажав Shift+Alt+W. Вставляемый <div> выбирается текущим элементом, так что вы можете легко отредактировать его, заменив на любой желаемый элемент, и закрывающий тег изменится автоматически. (С VS2017)
2. Скопируйте любой фрагмент кода JSON и вставьте его как строго типизированный класс .NET в любой файл кода C# или VB (см. картинку). (С VS2013)
3. Вам не нужно писать кавычки вокруг имён свойств JSON. При добавлении двоеточия после имени свойства Visual Studio вставит кавычки автоматически. (С VS2015)
4. Подсказки IntelliSense можно сделать полупрозрачными, просто удерживая клавишу Ctrl после того, как они появляются. (С VS2010)
5. Вместо перепечатывания скобок для отображения подсказки по параметрам метода, нажмите Ctrl+Shift+Пробел, чтобы отобразить подсказку по текущей перегруженной версии метода. (С 2010)
Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-tips-and-tricks/
29. Редактор Visual Studio
1. Легко оборачивайте элементы HTML в <div>, нажав Shift+Alt+W. Вставляемый <div> выбирается текущим элементом, так что вы можете легко отредактировать его, заменив на любой желаемый элемент, и закрывающий тег изменится автоматически. (С VS2017)
2. Скопируйте любой фрагмент кода JSON и вставьте его как строго типизированный класс .NET в любой файл кода C# или VB (см. картинку). (С VS2013)
3. Вам не нужно писать кавычки вокруг имён свойств JSON. При добавлении двоеточия после имени свойства Visual Studio вставит кавычки автоматически. (С VS2015)
4. Подсказки IntelliSense можно сделать полупрозрачными, просто удерживая клавишу Ctrl после того, как они появляются. (С VS2010)
5. Вместо перепечатывания скобок для отображения подсказки по параметрам метода, нажмите Ctrl+Shift+Пробел, чтобы отобразить подсказку по текущей перегруженной версии метода. (С 2010)
Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-tips-and-tricks/
День сто шестьдесят четвёртый. #ВопросыНаСобеседовании
Самые часто задаваемые вопросы на собеседовании по .NET
6. Что такое IL?
Common Intermediate Language (сокращённо CIL или IL) — промежуточный язык, разработанный Microsoft для платформы .NET Framework. Ранее язык назывался Microsoft Intermediate Language (MSIL), однако был переименован для создания стандарта ECMA-335.
IL - это набор независимых от процессора инструкций, которые генерируются компилятором языка при компиляции проекта. В частности, код IL генерируют все компиляторы .NET, входящие в Visual Studio (C#, Managed C++, Visual Basic .NET, Visual J# .NET). Код IL не является исполняемым, но далее обрабатывается средой CLR или другими средами выполнения в исполняемый код. Сборки приложения .NET написаны на IL.
Особенности:
Инструкции IL соответствуют коду, написанному на языке .NET и используемому для загрузки, хранения, инициализации и вызова методов на объектах, а также для арифметических и логических операций, управления потоком исполнения, прямого доступа к памяти, обработки исключений и других операции. JIT-компилятор в CLR преобразует код IL в машинный код, который затем исполняется операционной системой.
По синтаксису и мнемонике IL напоминает язык ассемблера. Его можно рассматривать как ассемблер виртуальной машины .NET. В то же время IL содержит некоторые достаточно высокоуровневые конструкции, повышающие его уровень по сравнению с ассемблером для любой реально существующей машины, и писать код непосредственно на IL легче, чем на ассемблере для реальных машин. Поэтому IL можно рассматривать как своеобразный «высокоуровневый ассемблер».
Выгоды:
1) Взаимодействие языков, так как код на любом языке .NET компилируется в IL.
2) Одинаковая производительность для всех языков .NET.
3) Поддержка различных сред выполнения.
Источники:
- https://ru.wikipedia.org/wiki/Common_Intermediate_Language
- https://www.dotnetfunda.com/interviews/show/3948/what-is-msil
Самые часто задаваемые вопросы на собеседовании по .NET
6. Что такое IL?
Common Intermediate Language (сокращённо CIL или IL) — промежуточный язык, разработанный Microsoft для платформы .NET Framework. Ранее язык назывался Microsoft Intermediate Language (MSIL), однако был переименован для создания стандарта ECMA-335.
IL - это набор независимых от процессора инструкций, которые генерируются компилятором языка при компиляции проекта. В частности, код IL генерируют все компиляторы .NET, входящие в Visual Studio (C#, Managed C++, Visual Basic .NET, Visual J# .NET). Код IL не является исполняемым, но далее обрабатывается средой CLR или другими средами выполнения в исполняемый код. Сборки приложения .NET написаны на IL.
Особенности:
Инструкции IL соответствуют коду, написанному на языке .NET и используемому для загрузки, хранения, инициализации и вызова методов на объектах, а также для арифметических и логических операций, управления потоком исполнения, прямого доступа к памяти, обработки исключений и других операции. JIT-компилятор в CLR преобразует код IL в машинный код, который затем исполняется операционной системой.
По синтаксису и мнемонике IL напоминает язык ассемблера. Его можно рассматривать как ассемблер виртуальной машины .NET. В то же время IL содержит некоторые достаточно высокоуровневые конструкции, повышающие его уровень по сравнению с ассемблером для любой реально существующей машины, и писать код непосредственно на IL легче, чем на ассемблере для реальных машин. Поэтому IL можно рассматривать как своеобразный «высокоуровневый ассемблер».
Выгоды:
1) Взаимодействие языков, так как код на любом языке .NET компилируется в IL.
2) Одинаковая производительность для всех языков .NET.
3) Поддержка различных сред выполнения.
Источники:
- https://ru.wikipedia.org/wiki/Common_Intermediate_Language
- https://www.dotnetfunda.com/interviews/show/3948/what-is-msil
День сто шестьдесят шестой. #ВопросыНаСобеседовании
Самые часто задаваемые вопросы на собеседовании по .NET
7. Что такое JIT-компилятор?
В .NET Framework все языки .NET используют CLR, что решает проблему установки отдельных сред выполнения для каждого из языков программирования. Если на компьютере установлена общеязыковая среда исполнения Microsoft .NET, она может работать на любом языке, совместимом с Microsoft .NET. Языки .NET компилируются в промежуточный язык IL. Перед выполнением IL должен быть преобразован компилятором Just-In-Time (JIT) в машинный код, который представляет собой специфические для процессора команды на той же компьютерной архитектуре, что и JIT компилятор.
Процесс компиляции промежуточного кода в машинный называется JIT-компиляцией Just-In-Time, потому что он не происходит до тех пор, пока сборка не будет размещена на целевой машине. Причина, по которой сборка не компилируется заранее, заключается в том, что можно использовать конкретный JIT-компилятор для вашей ОС и типа процессора. В результате сборка компилируется в максимально быстрый машинный код, оптимизируется и улучшается для вашей конкретной конфигурации.
Вместо того чтобы использовать время и память для преобразования всего IL кода в машинный код, он преобразуется по мере необходимости во время исполнения и сохраняется в результирующем машинном коде, чтобы он был доступен для последующих вызовов.
Среда исполнения предоставляет и другой режим компиляции, называемый генерацией кода во время установки. Режим генерации кода во время установки преобразует IL в машинный код, как это делает обычный JIT-компилятор, но одновременно конвертирует большие блоки кода, сохраняя результирующий машинный код для использования при последующей загрузке и исполнени сборки. Как часть компиляции IL в машинный код, код должен пройти процесс проверки, если администратор не установил политику безопасности, которая позволяет коду обходить проверку. Верификация проверяет IL и метаданные, чтобы выяснить, можно ли определить, что код безопасен по типу, то есть известно, что он имеет доступ только к тем ячейкам памяти, к которым у него есть права доступа.
Источник: https://www.c-sharpcorner.com
Самые часто задаваемые вопросы на собеседовании по .NET
7. Что такое JIT-компилятор?
В .NET Framework все языки .NET используют CLR, что решает проблему установки отдельных сред выполнения для каждого из языков программирования. Если на компьютере установлена общеязыковая среда исполнения Microsoft .NET, она может работать на любом языке, совместимом с Microsoft .NET. Языки .NET компилируются в промежуточный язык IL. Перед выполнением IL должен быть преобразован компилятором Just-In-Time (JIT) в машинный код, который представляет собой специфические для процессора команды на той же компьютерной архитектуре, что и JIT компилятор.
Процесс компиляции промежуточного кода в машинный называется JIT-компиляцией Just-In-Time, потому что он не происходит до тех пор, пока сборка не будет размещена на целевой машине. Причина, по которой сборка не компилируется заранее, заключается в том, что можно использовать конкретный JIT-компилятор для вашей ОС и типа процессора. В результате сборка компилируется в максимально быстрый машинный код, оптимизируется и улучшается для вашей конкретной конфигурации.
Вместо того чтобы использовать время и память для преобразования всего IL кода в машинный код, он преобразуется по мере необходимости во время исполнения и сохраняется в результирующем машинном коде, чтобы он был доступен для последующих вызовов.
Среда исполнения предоставляет и другой режим компиляции, называемый генерацией кода во время установки. Режим генерации кода во время установки преобразует IL в машинный код, как это делает обычный JIT-компилятор, но одновременно конвертирует большие блоки кода, сохраняя результирующий машинный код для использования при последующей загрузке и исполнени сборки. Как часть компиляции IL в машинный код, код должен пройти процесс проверки, если администратор не установил политику безопасности, которая позволяет коду обходить проверку. Верификация проверяет IL и метаданные, чтобы выяснить, можно ли определить, что код безопасен по типу, то есть известно, что он имеет доступ только к тем ячейкам памяти, к которым у него есть права доступа.
Источник: https://www.c-sharpcorner.com
День сто шестьдесят седьмой. #МоиИнструменты
Пишите Код Лучше и Быстрее с Помощью Анализаторов Кода Roslyn
Roslyn, платформа компилятора .NET, помогает вам обнаруживать ошибки еще до того, как вы запустите свой код. Одним из примеров является анализатор проверки орфографии, встроенный в Visual Studio. Допустим, вы создаете статический метод и неправильно написали слово static как statc. Вы сможете увидеть эту орфографическую ошибку до того, как запустите свой код.
Анализаторы Roslyn также могут отображать советы по автоматическому исправлению кода с помощью значка лампочки Visual Studio, который позволяет немедленно исправить код.
Но что, если бы вы могли обнаруживать еще больше ошибок?
Коллекции анализаторов Roslyn обеспечивают более подробный анализ кода, но не поставляются со стандартными инструментами Visual Studio. Начиная с Visual Studio 2017 версии 15.8, их можно установить в проект как пакет NuGet. Просто поищите в онлайн пакетах Microsoft.CodeAnalysis.FxCopAnalyzers.
После установки пакета вы можете настроить правила анализатора в окне Solution Explorer. Он появится в блоке References или Dependencies. Если развернуть блок анализаторов, а затем развернуть одну из сборок, вы сможете увидеть все наборы правил. Вы можете просмотреть свойства набора правил, включая его описание, уровень критичности по умолчанию и ссылку на статью с подробным описанием правил, в окне Properties (по правому щелчку мыши или нажав Alt+Enter).
Правила имеют несколько уровней критичности:
- “i” в кружке – Информационное (Info)
- “!” в треугольнике – Предупреждение (Warning)
- “x” в кружке – Ошибка (Error)
- “i” в кружке на светлом фоне – Скрытое (Hidden)
- “↓” в кружке – Отсутствует (None)
Вы можете установить критичность наборов правил в обозревателе решения. Щёлкните правой кнопкой на наборе правил и выберите Set Rule Set Severity. Например, если вы установите серьезность набора правил на Warning, вы получите предупреждение в своем коде там, где эти правила нарушаются. Можно добавлять собственные анализаторы кода, инструкция здесь: https://docs.microsoft.com/ru-ru/dotnet/csharp/roslyn-sdk/tutorials/how-to-write-csharp-analyzer-code-fix
Источник: https://devblogs.microsoft.com/dotnet/write-better-code-faster-with-roslyn-analyzers/
Пишите Код Лучше и Быстрее с Помощью Анализаторов Кода Roslyn
Roslyn, платформа компилятора .NET, помогает вам обнаруживать ошибки еще до того, как вы запустите свой код. Одним из примеров является анализатор проверки орфографии, встроенный в Visual Studio. Допустим, вы создаете статический метод и неправильно написали слово static как statc. Вы сможете увидеть эту орфографическую ошибку до того, как запустите свой код.
Анализаторы Roslyn также могут отображать советы по автоматическому исправлению кода с помощью значка лампочки Visual Studio, который позволяет немедленно исправить код.
Но что, если бы вы могли обнаруживать еще больше ошибок?
Коллекции анализаторов Roslyn обеспечивают более подробный анализ кода, но не поставляются со стандартными инструментами Visual Studio. Начиная с Visual Studio 2017 версии 15.8, их можно установить в проект как пакет NuGet. Просто поищите в онлайн пакетах Microsoft.CodeAnalysis.FxCopAnalyzers.
После установки пакета вы можете настроить правила анализатора в окне Solution Explorer. Он появится в блоке References или Dependencies. Если развернуть блок анализаторов, а затем развернуть одну из сборок, вы сможете увидеть все наборы правил. Вы можете просмотреть свойства набора правил, включая его описание, уровень критичности по умолчанию и ссылку на статью с подробным описанием правил, в окне Properties (по правому щелчку мыши или нажав Alt+Enter).
Правила имеют несколько уровней критичности:
- “i” в кружке – Информационное (Info)
- “!” в треугольнике – Предупреждение (Warning)
- “x” в кружке – Ошибка (Error)
- “i” в кружке на светлом фоне – Скрытое (Hidden)
- “↓” в кружке – Отсутствует (None)
Вы можете установить критичность наборов правил в обозревателе решения. Щёлкните правой кнопкой на наборе правил и выберите Set Rule Set Severity. Например, если вы установите серьезность набора правил на Warning, вы получите предупреждение в своем коде там, где эти правила нарушаются. Можно добавлять собственные анализаторы кода, инструкция здесь: https://docs.microsoft.com/ru-ru/dotnet/csharp/roslyn-sdk/tutorials/how-to-write-csharp-analyzer-code-fix
Источник: https://devblogs.microsoft.com/dotnet/write-better-code-faster-with-roslyn-analyzers/