Статьи

Какое исключение бросать в swith, если case не нашлось?

May 25, 2020

В чём проблема

Если написав очередной switch/case, вы останавливались и задумывались - а нужно ли вообще обрабатывать default-ветку, а если обрабатывать, то бросать ли исключение, а если бросать то какое, а нормально ли вообще, что у меня эти switch/case по всей кодовой базе дублируются ? - то на эти вопросы я попробовал сформулировать своё мнение в этом тексте.

enum SomeEnum
{
  One,
  Two,
  Three
}

void someFunc()
{
  SomeEnum value = someOtherFunc();
  switch(value)
  {
     case One:
       //Обрабатываем
       //...
       break;
     case Two:
      //Обрабатываем
       //...
       break;
     default:
       //Что-нибудь делаем ?
  }
}
Продолжить чтение

Инкапсуляция - что ты такое?

May 08, 2020

Вроде живёшь себе спокойно, думаешь, что понимаешь кое-что в программировании, но вдруг во время беседы в зуме с друзьями программистами говоришь:

Инкапсуляция? - Ну это сокрытие деталей реализации.

А тебе в ответ:

Вообще-то инкапсуляция - это объединение данных и методов оперирующих этими данными, а сокрытие тут совсем не обязательно.

Начинаем разбираться, идём в Википедию, а она пишет:

Под инкапсуляцией понимают либо объединение вместе данных и методов, либо скрытие внутренних данных и состояния объекта и ограничение прямого доступа к ним, либо комбинацию этих определений. В общем разные авторы по разному её понимают.

Это не дословная цитата

И в качестве примера рассматривающего инкапсуляции исключительно как механизма для объединения данных и методов вместе даётся ссылка на статью “Encapsulation is not information hiding” - а Information Hiding - это по сути и есть сокрытие деталей реализации, так что явный аргумент пока не в мою пользу.

Но я то инкапсуляцию без сокрытия деталей реализации никогда не представлял, да, мы объединяем вместе данные и методы, но не это главное, а у статьи, к тому же, никаких рефференсов на материалы, которые она использовала нет, так что предлагаю посмотреть ещё источники.

Продолжить чтение

Volatile, модели и барьеры памяти

November 13, 2019

Сегодня будем разбираться с volatile и всем, что с ним связано. Тема эта интересна тем, что чтобы полностью её понимать необходимо опуститься вплоть до уровня процессора и даже узнать чем отличаются разные процессорные архитектуры в плане работы с памятью. Так как материал объёмный и сложный, то не буду пытаться, что-то объяснить сам, а буду давать ссылки.

Что о volatile нам рассказал Рихтер

У Рихтера в книге для volatile отведёно 7 страниц и этого явно недостаточно, чтобы хорошенько разобраться с темой.

Компилятор C#, JIT-компилятор и даже сам процессор могут оптимизировать ваш код. В процессе оптимизации кода компилятором C#, JIT-компилятором и процессором гарантируется сохранение его назначения. То есть с точки зрения одного потока метод делает то, зачем мы его написали, хотя способ реализации может отличаться от описанного исходном коде. Однако при переходе к многопоточной конфигурации ситуация может измениться.

То есть, если у вас многопоточное приложение с разделяемыми несколькими потоками данными (например полями класса), то у вас нет гарантии того, что данные в эти разделяемые поля будут записаны одним потоком и прочитаны другим потоком именно в том порядке, в котором вы их написали в своём коде.

Продолжить чтение

Представление чисел с плавающей точкой в памяти в дотнете

September 01, 2019

Поехали

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

У Джона Скита есть две коротенькие статьи на эту тему, первая: Binary floating point and .NET - про double и float, вторая: Decimal floating point in .NET - про decimal (в этой статье я не касаюсь Decimal).

Сам Скит рекомендует к прочтению эту статью: Floating Point in .NET part 1: Concepts and Formats - она более подробная и позволит более основательно разобраться в вопросе.

Также в процессе подготовки этого материала я нашёл статью на русском: Взгляд со стороны: Стандарт IEEE754 - она в целом о стандарте хранения чисел IEEE754, статья основательная, но довольно абстрактная и её не назовёшь лёгким, доступным материалом.

В этой же статье я больше сосредоточюсь на просмотре конкретных байтовых представлениях чисел в памяти, разобрав как они получаются. Мне кажется, таких конкретных примеров не хватает в статьях выше для лучшего понимания.

Продолжить чтение

Управление жизненным циклом объектов в Castle Windsor

February 21, 2017

В этой статье я хотел бы разобрать вопрос управления временем жизни объектов при использовании Inversion of Control контейнера Castle Windsor.

Мы рассмотрим такие вопросы как:

  • Как Castle Windsor управляет жизненным циклом создаваемых объектов.

  • Можно ли вызывать Dispose() метод у полученных из контейнера объектов.

  • Когда нужно вызывать _container.Release(someObjectInstance).

  • Как работают различные Lifestyle’ы и Lifecycle’ы Castle Windsor.

Castle Windsor и жизненный цикл создаваемых им объектов

Одна из ключевых обязанностей IoC-контейнера - это управление жизненным циклом создаваемых им объектов. Контейнер создает объект, настраивает его и отдаем вам, после чего вы можете им пользоваться, а когда объект становится не нужен - производит действия подготавливающие объект к уничтожению.

Давайте рассмотрим пример:

public class UnitOfWork
{
   public void Init()
   {
      // some initialization logic...
   }
   public void Commit()
   {
      // commit or rollback the UoW
   }
}
Продолжить чтение

ASP.NET 5 Новый тип проекта и работа с Grunt

December 01, 2015

Несмотря на то, что статья использует название “ASP.NET 5”, она не имеет никакого отношения к тому, что в 2020 году могут понимать под ASP.NET 5. ASP.NET 5 назывался ASP.NET Core до релиза первой версии.

В этой статье я опишу новый проект веб-приложения ASP.NET 5, а также расскажу о настройке и использовании Grunt в нем.

Проект ASP.NET 5

Мы будем использовать Visual Studio 2015 Community Edition - она бесплатна для личного использования.

После ее установки и запуска, выберите “File”, “New”, “Project”, а затем в разделе “Templates”, “Visual C#”, “Web” выберите “ASP.NET Web Application”.

Создаем новый Asp.NET 5 проект

Продолжить чтение

Погружение в ASP.NET 5 Runtime

November 27, 2015

Несмотря на то, что статья использует название “ASP.NET 5”, она не имеет никакого отношения к тому, что в 2020 году могут понимать под ASP.NET 5. ASP.NET 5 назывался ASP.NET Core до релиза первой версии. Так как статья писалась до релиза ASP.NET Core, в ней также используются имена актуальные на тот момент, в релизе первой версии многие вещи были переименованы (например DNX в dotnet)

Последняя версия этой статьи опубликована на habrahabr.ru

Вступление от переводчика

Данная статья является переводом ASP.NET 5 - A Deep Dive into the ASP.NET 5 Runtime - введения в архитектуру DNX Runtime и построенного на нем ASP.NET 5. Так как оригинальная статья была написана в марте 2015 года, во время, когда ASP.NET 5 был еще в стадии активной разработки (примерно beta 3), многое в ней устарело. Поэтому при переводе вся информация была актуализирована до текущей версии ASP.NET 5 (RC1), также были добавлены ссылки на связанные ресурсы (в основном на docs.asp.net) и исходный код на GitHub (смотрите только в случаях, если вам интересна реализация). Приятного погружения!

.NET Runtime Environment (DNX)

ASP.NET базируется на гибком, кроссплатформенном runtime, который может работать с разными .NET CLR (.NET Core CLR, Mono CLR, .NET Framework CLR). Вы можете запустить ASP.NET 5 используя полный .NET Framework или можете запустить используя новый .NET Core (docs.asp.net: Introducing .NET Core), который позволяет вам просто копировать все необходимые библиотеки вместе с приложением в существующее окружение, без изменения чего-либо еще на вашей машине. Используя .NET Core вы также можете запустить ASP.NET 5 кроссплатформенно на Linux (docs.asp.net: Installing ASP.NET 5 On Linux) и Mac OS (docs.asp.net: Installing ASP.NET 5 On Mac OS X).

Продолжить чтение

Маршрутизация в ASP.NET 5

August 15, 2015

Эта статья была опубликована в корпоративном блоге Microsoft на habrahabr.ru: Ссылка.

Несмотря на то, что статья использует название “ASP.NET 5”, она не имеет никакого отношения к тому, что в 2020 году могут понимать под ASP.NET 5. ASP.NET 5 назывался ASP.NET Core до релиза первой версии. Информация в статье актуальна для ASP.NET Core первой и второй версии, в третьей же версии фреймворка маршрутизация была сильно переделана.

Сегодня мы посмотрим на систему маршрутизации в ASP.NET 5.

Как была организована система маршрутизации до ASP.NET 5

Маршрутизация до ASP.NET 5 осуществлялась с помощью ASP.NET модуля UrlRoutingModule. Модуль проходил через коллекцию маршрутов (как правило объектов класса Route) хранящихся в статическом свойстве Routes класса RouteTable, выбирал маршрут, который подходил под текущий запрос и вызывал обработчик маршрута, который хранился в свойстве RouteHandler класса Route - каждый зарегистрированный маршрут мог иметь собственный обработчик. В MVC-приложении этим обработчиком был MvcRouteHandler, который брал на себя дальнейшую работу с запросом.

Маршруты в коллекцию RouteTable.Routes мы добавляли в процессе настройки приложения.

Типичный код настройки системы маршрутизации в MVC приложении:

RouteTable.Routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

Где MapRoute - extension-метод, объявленный в пространстве имен System.Web.Mvc, который добавлял в коллекцию маршрутов в свойстве Routes новый маршрут используя MvcRouteHandler в качестве обработчика.

Продолжить чтение

Ковариация и контрвариация C#

September 17, 2014

В этой статье я бы хотел дать свое объяснение как работает ковариация и контрвариация в C#.

Что такое ковариация и контрвариация

Предположим у нас есть два типа - тип Animal и тип Cat и Cat наследуется от Animal - то есть мы можем Cat привести к Animal и есть третий тип, который использует типы Cat и Animal, допустим это тип Zoo. Тип Zoo является ковариантным, если мы можем Zoo<Cat> привести к Zoo<Animal> и является контрвариантным, если мы можем Zoo<Animal> привести к Zoo<Cat>. Я использовал синтаксис обобщения в примере, но вообще - это будет не обязательно обобщение - смысл в том, что один тип использует другие типы и поддерживает приведения этих типов в контексте себя.

Классическим является пример с приведением списка:

IEnumerable<string> strCollection = new List<string>() {"string"};
IEnumerable<object> objectCollection = strCollection;

string - наследуется от object и коллекцию string мы можем привести к коллекции object.

То есть, если некоторый метод, в качестве принимаемого параметра использует IEnumerable<object>, то мы можем передать в этот метод переменную с типом IEnumerable<string> и она будет приведена к нужному типу.

Смысл ковариации и контрвариации в C#

Ковариация и контрвариация в C# существует только в контексте методов. Давайте представим, что под типом Zoo из примера выше мы подразумеваем метод, а типы Cat и Animal - это типы возвращемого значения или входного параметра - то есть под Zoo<SomeType> (где SomeType - Cat или Animal) мы подразумеваем:

Продолжить чтение

Жизненный цикл ASP.NET приложения

July 08, 2014

В статье описывается жизненный цикл приложения классического ASP.NET, информация не актуальна для ASP.NET Core

Цикл жизни ASP.NET приложения - это все что происходит с ним от его старта, до его завершения.

Цикл жизни приложения начинается тогда, когда получен первый запрос любого ресурса нашего приложения и заканчивается, когда приложение выгружается из памяти.

Стадии цикла жизни приложения Asp .NET

Получен первый запрос ресурса нашего Asp .NET приложения

  1. Когда получен первый запрос любого ресурса приложения, экземпляр класса ApplicationManager создает Домен приложений, для запуска нашего приложения - каждое приложение Asp .Net загружается в собственный домен приложений и работает в нем - это предоставляет необходимый уровень изоляции приложений запущенных на одном сервере.

  2. В пределах этого домена приложений, создается инстанс класса HostingEnvironment, который предоставляет доступ к информации о нашем приложении, такой как имя и папка, где приложение находится.

Продолжить чтение

Как .NET хранит объекты в памяти

July 06, 2013

Причиной многих заблуждений относительно того как .NET хранит объекты в памяти, является ошибочное представление, что значимые типы всегда хранятся в стеке (stack), а ссылочные в куче (heap). На самом деле ссылочные типы - всегда хранятся в куче, а вот значимые типы могут храниться как в куче, так и в стеке.

Все локальные переменные (local variables) и параметры метода хранятся в стеке. Это касается переменных и параметров и значимых (value types) и ссылочных типов (reference types). Разница между ними в том, что они хранят. Переменные и параметры значимых типов - хранят само значение переменной. А переменные и параметры ссылочных типов - хранят ссылку на объект расположенный в куче.

Теперь рассмотрим поля (fields).

Поля являются частью сложных типов, таких как классы (class) и структуры (struct). Когда память выделяется для хранения экземпляра сложного типа, она должна также включать место для хранения и полей, который этот тип содержит. Для полей значимого типа место выделяется для хранения самого его значения, а для полей ссылочного типа место выделяется для хранения ссылки на объект в куче.

Продолжить чтение