.NET Разработчик
6.58K subscribers
446 photos
4 videos
14 files
2.14K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День двести восемьдесят девятый. #Оффтоп
Продолжаю тему «ютуб подкинул в рекоммендациях».
Если вы программист, но не знаете, кто такой Дядя Боб, то самое время с ним познакомиться, потому
что велик шанс, что дядя уже программировал ещё до того, как родились ваши родители.
Как зародилось программирование? Сколько времени занимал процесс компиляции кода в 50-х? Как бы
выглядел ламповый айфон? Как появился Agile? Куда, чёрт возьми, делись женщины-программисты? До
чего мы дошли и куда катится программистский мир?
Обо всём этом и о многом другом с шутками, прибаутками и профессиональными байками рассказывает сам
мэтр. Так что, если у вас есть полтора часа свободного времени, очень рекомендую.
Кстати несмотря на то, что C# в видео не упоминается, книжка по шарпам у дяди Боба тоже есть шьгл
в помощь).
Ну и… да, стоит ли в который раз напоминать, что всё самое интересное в программировании на
английском https://youtu.be/ecIWPzGEbFc
День двести девяностый. #ЗаметкиНаПолях
Больше возможностей передачи по ссылке. Продолжение
In-параметры (C# 7.2)
В C#7.2 добавлен новый модификатор параметров in, похожий на ref или out. Когда параметр имеет модификатор in, предполагается, что метод не будет изменять значения параметра, поэтому переменная может быть передана по ссылке, чтобы избежать копирования. Внутри метода параметр in действует как локальная ref readonly переменная.
Разница между параметром in и параметром ref или out в том, что вызывающей стороне не нужно указывать модификатор in для аргумента. Если модификатор in отсутствует, компилятор передаст аргумент по ссылке, если передана переменная, или скопирует значение в скрытую локальную переменную, которую передаст по ссылке. Если вызывающая сторона указывает модификатор in явно, вызов будет действителен, только если аргумент может быть передан по ссылке напрямую:
static void PrintDateTime(in DateTime value)
{
string text = value.ToString(
"yyyy-MM-dd'T'HH:mm:ss",
CultureInfo.InvariantCulture);
Console.WriteLine(text);
}
static void Main()
{
DateTime start = DateTime.UtcNow;
//неявная передача по ссылке
PrintDateTime(start);
//явная передача по ссылке
PrintDateTime(in start);
//значение копируется в скрытую переменную
PrintDateTime(start.AddMinutes(1));
//ошибка компиляции:
//значение не может явно передаваться по ссылке
PrintDateTime(in start.AddMinutes(1));
}
Может показаться, что, если вы не изменяете параметр в методе, можно сделать его in-параметром. Но это опасное предположение. Компилятор останавливает метод от изменения параметра, но он ничего не может сделать с другим кодом, изменяющим его. Вы должны помнить, что параметр in является псевдонимом для адреса хранения значения, которое может изменить другой код. Например, параметр in может оказаться псевдонимом для поля в том же классе. В этом случае любые изменения в поле (в самом методе или в другом коде) будут видны через in-параметр. Но из кода это не очевидно ни в вызывающем коде, ни в самом методе. Еще сложнее предсказать, что произойдёт, если задействовано несколько потоков.

Перегрузка in-параметров
Правила те же, что и для ref и out параметров. Нельзя использовать перегрузки, отличающиеся только модификатором ref/out/in. Но вы можете перегрузить метод с обычным параметром методом с in-параметром:
void Method(int x) { ... }
void Method(in int x) { ... }

Тогда перегрузка будет использоваться только при вызове с явным указанием in-параметра.

Советы по применению
Во-первых, in-параметры предназначены для повышения производительности. Как правило, не стоит вносить какие-либо изменения в ваш код для повышения производительности, пока вы не измерили производительность очевидным и повторяемым способом и не убедились, что изменения достигают вашей цели.
Основная проблема с in-параметрами в том, что они могут значительно усложнить анализ вашего кода. Вы можете прочитать значение одного и того же параметра дважды и получить разные результаты несмотря на то, что ваш метод ничего не изменял. Это усложняет написание правильного кода и упрощает написание кода, который только кажется правильным.
Используйте in-параметры только тогда, когда есть ощутимый и значительный выигрыш в производительности. Это наиболее вероятно, когда задействованы большие структуры.
Избегайте использования in-параметров в общедоступных API.
⚠️ Рассмотрите возможность использования открытого метода в качестве барьера против изменений, а затем используйте in-параметры в закрытом методе, чтобы избежать копирования.
⚠️ Рассмотрите возможность явного использования модификатора in при вызове метода, который принимает in-параметр. Это лишний раз сообщит о ваших намерениях.

Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 13.
День двести девяносто первый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
8. Правило Бойскаута
У бойскаутов есть правило: «Всегда оставляй место стоянки чище, чем оно было до тебя». Если стоянка загажена, вы её очищаете независимо от того, кто её загадил. Вы намеренно улучшаете окружающую среду для следующей группы отдыхающих. (На самом деле, в оригинале это правило, написанное отцом движения скаутов Робертом Стивенсоном Смитом Баден-Пауэлом, звучит так: «Старайтесь оставить этот мир чуть лучше, чем он был до вашего прихода».)
Что если бы мы следовали аналогичному правилу в нашем коде: «Всегда оставляйте код чище, чем он был, когда вы его проверяли»? Независимо от того, кто его автор, что, если мы всегда прилагали бы некоторые усилия, даже самые минимальные, чтобы улучшить код? Какой был бы результат?
Я думаю, что, если бы мы все следовали этому простому правилу, мы бы увидели конец неумолимого ухудшения наших программных систем. Вместо этого наши системы постепенно становились бы всё лучше и лучше по мере их развития. А команды заботились бы о системе в целом, а не каждый член о своей маленькой части.
Я не думаю, что это правило слишком трудное для выполнения. Вам не нужно доводить каждый блок программы до совершенства при каждой проверке. Просто нужно сделать его немного лучше. Конечно, это означает, что любой код, который вы добавляете, должен быть чистым. Это также означает, что перед повторной проверкой блока вы улучшите ещё хоть что-нибудь. Вы можете просто переименовать плохо названную переменную или разбить одну длинную функцию на две маленькие, разорвать циклическую зависимость или добавить интерфейс для отделения публичного API от деталей реализации.
Честно говоря, для меня это звучит как обычное правило этикета, как, например, мыть руки после посещения туалета или бросать мусор в урну, а не на пол. Действительно, оставить беспорядок в коде должно быть столь же социально неприемлемым, как мусорить. Это должно быть что-то, чего просто нельзя делать.
Но в этом есть нечто большее. Забота о нашем собственном коде - это одно. Забота о коде команды - совсем другое. Команды помогают друг другу и убирают друг за другом. Они следуют правилу бойскаутов, потому что это хорошо для всех, а не только для них.

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Роберт Мартин (Дядя Боб)
День двести девяносто второй.
Сертификат Microsoft. Экзамен 70-486. Шаг первый
Итак, как я уже писал выше, я нацелился на сертификат «Microsoft® Certified Solutions Associate: Web Applications». Таким образом, мне нужно сдать ещё один экзамен «Developing ASP.NET MVC Web Applications».
Что можно сказать при беглом осмотре описания:
1. Список тем кажется гораздо обширнее, чем по языку C# (хотя и там было не мало).
2. Похоже, нужно изучить как Framework, так и Core, более того знать отличия.
3. Какое-то нереальное количество вопросов по Azure.
4. В отличие от языка C#, источников информации крайне мало. По крайней мере, из того, что мне удалось найти, три с половиной книги по ASP.NET MVC и пара видеокурсов на Pluralsight (с платной подпиской) по Azure. Это, конечно, не считая предлагаемых очных 5-дневных (sic!!!) курсов за 30-40 т.р. Чему там за 5 дней могут научить, решительно непонятно. Судя по программе курса на одном из сайтов, они там просто идут по книге Адама Фримена «ASP.NET MVC с примерами на C#», что составляет процентов 20 от списка тем экзамена.

В общем, пока перспективы не сильно радужные, подбираю книги по MVC, с Azure буду разбираться потом.

UPD: Немного покопавшись на сайте MSDN Channel 9, где был видеокурс для подготовки к экзамену по C#, нашёл аналогичный курс по ASP.NET MVC.
День двести девяносто третий. #ЗаметкиНаПолях
Объявление структур только для чтения (C#7.2)
C# долгое время неявно копировал структуры. Все это задокументировано в спецификации. Причина, по которой компилятор делает эту копию, состоит в том, чтобы избежать изменения поля, доступного только для чтения, кодом в свойстве (или методом, если вы его вызываете). Смысл поля только для чтения состоит в том, что ничто не может изменить его значение. Было бы странно, если бы readOnlyField.SomeMethod() мог изменять поле. C# рассчитан на то, что любые мутаторы (set) свойств будут изменять данные, поэтому они запрещены для полей только для чтения. Но даже аксессор (get) свойства может попытаться изменить значение. Поэтому скрытая копия - это эффективная мера безопасности.
Но что, если структура может пообещать, что она этого не сделает? В конце концов, большинство структур разработано, чтобы быть неизменяемыми. В C#7.2 вы можете применить модификатор readonly к объявлению структуры, чтобы это сделать:
public readonly struct YearMonthDay
{
public int Year { get; }
public int Month { get; }
public int Day { get; }
public YearMonthDay(int year, int month, int day) =>
(Year, Month, Day) = (year, month, day);
}
Вы можете применять модификатор только в том случае, если ваша структура действительно доступна только для чтения и поэтому соответствует следующим условиям:
1. Каждое поле и автоматически реализованное свойство экземпляра должны быть доступны только для чтения. Статические поля и свойства все ещё могут быть доступны для чтения и записи.
2. Вы можете обращаться к this только внутри конструкторов. Можно рассматривать this в структурах:
- как out-параметр в конструкторах (инициализирует поле);
- как ref-параметр в членах обычных структур (изменяет значение поля по ссылке);
- как in-параметр в членах структур только для чтения (читает значение поля по ссылке).

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

Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 13.
День двести девяносто четвёртый. #ЗаметкиНаПолях
Больше возможностей передачи по ссылке. Продолжение
Методы расширения с ref или in параметрами (C#7.2)
Предположим, у вас есть большая структура, которую вы не хотите копировать, и метод, который вычисляет результат на основе значений свойств этой структуры (например, длину трехмерного вектора). Хорошо, если структура предоставляет сам метод (или свойство), особенно когда она объявлена с модификатором readonly. Вы можете избежать копирования без проблем. Но, возможно, вы делаете что-то более сложное, что авторы структуры не предусмотрели. Рассмотрим структуру Vector3D только для чтения со свойствами X, Y и Z:
public readonly struct Vector3D
{
public double X { get; }
public double Y { get; }
public double Z { get; }
public Vector3D(double x, double y, double z)
{ X = x; Y = y; Z = z; }
}
Можно написать метод, принимающий структуру с параметром in, но это будет выглядеть не слишком красиво:
double magnitude = VectorUtilities.Magnitude(vector);
Есть методы расширения, но обычный метод расширения, подобный этому, будет копировать вектор при каждом вызове:
public static double Magnitude(this Vector3D vector)
Неприятно выбирать между производительностью и удобочитаемостью.
В C#7.2 вы можете написать методы расширения с модификатором ref или in для первого параметра. Модификатор может идти до или после this. Если выполняется только чтение значений, используйте in, если значения изменяются, то ref:
public static double Magnitude(this in Vector3D vec) => 
Math.Sqrt(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z);
public static void OffsetBy(this ref Vector3D orig, in Vector3D off) =>
orig = new Vector3D(orig.X + off.X, orig.Y + off.Y, orig.Z + off.Z);
Заметьте, что второй параметр в методе OffsetBy является параметром in. Мы максимально пытаемся избежать копирования.
Использовать методы расширения просто. Единственный, возможно, удивительный аспект заключается в том, что в отличие от обычных параметров ref, при вызове методов расширения с такими параметрами о них нет никакого упоминания:
var vector = new Vector3D(1.5, 2.0, 3.0);
var offset = new Vector3D(5.0, 2.5, -1.0);
vector.OffsetBy(offset);
Console.WriteLine($"({vector.X}, {vector.Y}, {vector.Z})");
Console.WriteLine(vector.Magnitude());
Вывод:
(6.5, 4.5, 2)
8.15475321515004
Вызов OffsetBy изменил переменную vector, как и предполагалось. Таким образом, метод OffsetBy делает нашу неизменяемую структуру Vector3D в некотором роде изменяемой. Этот функционал новый и лучших практик использования ещё не выведено, поэтому параметры ref пока стоит использовать с осторожностью.

Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 13.
This media is not supported in your browser
VIEW IN TELEGRAM
День двести девяносто пятый. #Оффтоп #МоиИнструменты
Object Exporter
В рабочем проекте логгер ошибок выкладывает сериализованные в JSON объекты в лог при возникновении ошибок. Возникла потребность сравнить состояние объекта из лога и состояние объекта в точке останова при дебаге. Начал копаться и нашёл расширение Object Exporter для Visual Studio. Он позволяет экспортировать объекты во время дебага и сериализовать их в код C# или в JSON или XML.
Варианты использования:
- Как описано выше, сравнение состояния объекта при дебаге.
- Поиск информации внутри объекта.
- Генерация инициализаторов объектов для юнит-тестов (сериализация в C#).
Судя по отзывам, есть несколько мелких косяков: давно не было обновлений, относительно медленная работа и (с чем я сам столкнулся) при экспорте в JSON вложенные объекты почему-то экспортируются без имени. Но ничего лучше я не нашёл. Если есть другие варианты, буду рад услышать предложения в чате
День двести девяносто шестой. #BestPractices
Советы по сериализации. Начало
Сериализация - это процесс преобразования объекта в формат, который можно легко сохранить или перенести. Например, вы можете сериализовать объект, передать его через Интернет с помощью HTTP и десериализовать его на конечном компьютере. Подробнее о процессе сериализации можно почитать тут.
Различают три основных типа сериализации:
- Data Contract
- XML
- Времени выполнения (бинарная или SOAP)

⚠️ РАССМОТРИТЕ возможность сериализации при разработке новых типов.

Выбор правильной технологии сериализации
⚠️ РАССМОТРИТЕ поддержку сериализации Data Contract, если экземпляры вашего типа, возможно, потребуется сохранять или использовать в веб-сервисах.
⚠️ РАССМОТРИТЕ поддержку сериализации XML вместо или в дополнение к Data Contract, если вам нужен больший контроль над форматом XML, который создается при сериализации типа. Это может быть необходимо в некоторых сценариях взаимодействия, где необходимо использовать конструкции XML, которые не поддерживаются сериализацией Data Contract, например, для создания атрибутов XML.
⚠️ РАССМОТРИТЕ поддержку сериализации времени выполнения, если экземпляры вашего типа должны перемещаться через границы .NET Remoting.

Поддержка сериализации Data Contract
Типы могут поддерживать сериализацию Data Contract, применяя атрибуты DataContract к типу и DataMember к элементам (полям и свойствам) типа.
⚠️ РАССМОТРИТЕ возможность сделать члены вашего типа открытыми, если тип может использоваться в средах с частичным доверием. В среде с полным доверием сериализаторы Data Contract могут сериализовать и десериализовать непубличные типы и члены.
❗️ НЕОБХОДИМО использовать и аксессор (get), и мутатор (set) для всех свойств, имеющих атрибут DataMember. В .NET Framework 3.5 SP1 некоторые свойства коллекции могут быть доступны только для чтения. Если тип не будет использоваться в средах с частичным доверием, аксессор и мутатор могут быть закрытыми.
⚠️ РАССМОТРИТЕ использование обратных вызовов сериализации для инициализации десериализованных экземпляров. За редкими исключениями, при десериализации объектов конструкторы не вызываются. Следовательно, любая логика, которая выполняется во время обычного создания объекта, должна быть реализована в методе обратного вызова. Методы обратного вызова помечаются атрибутами OnSerializing, OnSerialized, OnDeserializing, OnDeserialized.
⚠️ РАССМОТРИТЕ использование атрибута KnownType, чтобы указать конкретные типы, которые следует использовать при десериализации графа сложного объекта.
❗️ НЕОБХОДИМО учитывать обратную и прямую совместимость при создании или изменении сериализуемых типов. Помните, что сериализованные потоки новых версий вашего типа могут быть десериализованы в старую версию типа, и наоборот. Учтите, что члены данных, даже закрытые и внутренние, не могут изменять свои имена, типы или даже порядок в новых версиях типа, если не будут приняты особые меры для сохранения контракта с использованием явных параметров атрибутов Data Contract. Проверьте совместимость сериализации при внесении изменений в сериализуемые типы. Попробуйте десериализовать новую версию в старую и наоборот.
⚠️ РАССМОТРИТЕ реализацию IExtensibleDataObject, чтобы разрешить циклический переход между различными версиями типа. Интерфейс позволяет сериализатору гарантировать, что никакие данные не будут потеряны во время такого перехода. Свойство IExtensibleDataObject.ExtensionData используется для хранения любых данных из будущей версии типа, которые неизвестны текущей версии, и не могут быть сохранены в текущей версии. Когда текущая версия впоследствии сериализуется и десериализуется в будущую версию, дополнительные данные будут доступны в сериализованном потоке.

Продолжение следует…

Источник:
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/
День двести девяносто седьмой. #BestPractices
Советы по сериализации. Окончание

Поддержка XML-сериализации
Сериализация Data Contract является основной технологией сериализации в .NET Framework, но существуют сценарии, которые она не поддерживает. Например, она не даёт вам полного контроля над форматом XML, создаваемым или потребляемым сериализатором. Если требуется такой точный контроль, необходимо использовать сериализацию XML, и разработать типы с поддержкой этой технологии сериализации.
ИЗБЕГАЙТЕ разработки ваших типов специально для XML-сериализации, если только у вас нет веских оснований контролировать формат создаваемого XML. Эта технология сериализации была заменена сериализацией Data Contract, рассмотренной в предыдущем посте.
⚠️ РАССМОТРИТЕ реализацию интерфейса IXmlSerializable, если вы хотите получить больший контроль над форматом сериализованного XML, чем просто применение атрибутов XML-сериализации. Два метода интерфейса, ReadXml и WriteXml, позволяют полностью контролировать сериализованный поток XML. Вы также можете управлять схемой XML применяя атрибут XmlSchemaProvider.

Поддержка сериализации времени выполнения
Сериализация времени выполнения - это технология, используемая в .NET Remoting. Если вы думаете, что ваши типы будут транспортироваться с помощью .NET Remoting, вам необходимо убедиться, что они поддерживают сериализацию времени выполнения.
Базовая поддержка сериализации времени выполнения может быть обеспечена путем применения атрибута Serializable, а более сложные сценарии включают реализацию простого паттерна сериализации времени выполнения (реализуйте ISerializable и предоставьте конструктор сериализации).
⚠️ РАССМОТРИТЕ поддержку сериализации времени выполнения, если ваши типы будут использоваться в .NET Remoting. Например, пространство имен System.AddIn использует .NET Remoting, поэтому все типы, которыми обмениваются надстройки System.AddIn, должны поддерживать сериализацию времени выполнения.
⚠️ РАССМОТРИТЕ реализацию паттерна сериализации времени выполнения, если вы хотите полностью контролировать процесс сериализации. Например, преобразовывать данные по мере их сериализации или десериализации.Для этого нужно реализовать интерфейс ISerializable и предоставить специальный конструктор, который используется при десериализации объекта.
ИСПОЛЬЗУЙТЕ защищённый конструктор сериализации с двумя параметрами, как показано ниже:
[Serializable]
public class Person : ISerializable
{
protected Person(SerializationInfo info, StreamingContext context) {…}
}
❗️ НЕОБХОДИМО явно реализовать элементы ISerializable.
❗️ НЕОБХОДИМО применить атрибут SecurityPermission(SecurityAction.LinkDemand) к реализации ISerializable.GetObjectData. Это гарантирует, что только полностью доверенный код получит доступ к методу.

Источник: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/
День двести девяносто восьмой. #Оффтоп
Хорошая картинка, посвящённая дизайну, основанному на пользовательском опыте, (UX-driven design) из лекции Дино Эспозито на конференции DotNext. С точки зрения пользователя наш софт – это слой представления и чёрный ящик. Поэтому дизайн, основанный на пользовательском опыте, предполагает сначала выяснение, какой функционал требуется конечному пользователю, а только затем дизайн кнопок - триггеров операций в бэкэнде, который для пользователя представляет собой чёрный ящик. То, что в чёрном ящике, пользователя не волнует. Важны команды, которые он туда посылает и результаты, которые он из него получает. Когда есть согласие с пользователем относительно презентационного слоя, большинство проблем использования, обычно возникающих после релиза продукта, решаются на ранних этапах проектирования.
Полная лекция (на английском): https://youtu.be/xeMbZyhzoAw
День двести девяносто девятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
9. Сначала проверьте свой код, прежде чем обвинять других
Признайтесь, каждому из нас хоть раз было трудно признаться себе, что наш код не работает. Этого
просто не может быть! Это настолько невероятно, что наверняка именно в этот раз проблема должна
быть в компиляторе/фреймворке/библиотеке.
Но на самом деле это крайне – крайне! – маловероятно, что работа кода нарушается из-за ошибки в
компиляторе, интерпретаторе, ОС, сервере приложений, фреймворке, базе данных, диспетчере памяти или любом другом компоненте системного программного обеспечения. Да, эти ошибки существуют, но они встречаются гораздо реже, чем нам хотелось бы верить.
Однажды я в самом деле столкнулся с ошибкой компилятора, который при оптимизации выкидывал
переменную цикла, но грешил на ошибку в компиляторе или ОС я гораздо чаще. Я тратил много своего времени и времени техподдержки, только чтобы в итоге чувствовать себя идиотом каждый раз, когда в конце концов оказывалось, что ошибка была у меня.
Если инструмент широко распространён и используется множеством людей в различных ситуациях, то причин сомневаться в его качестве очень мало. Конечно, если это бета-версия инструмента или он используется всего несколькими людьми? или же это проект с открытым кодом на ранних стадиях разработки, могут быть веские основания подозревать его.
Но учитывая, насколько редки ошибки в компиляторах, вы гораздо лучше потратите своё время и энергию на поиск ошибки в своем коде, чем на доказательство того, что компилятор не прав. Применимы все обычные рекомендации по отладке.
Когда кто-то другой сообщает о проблеме, которую вы не можете воспроизвести, сходите и посмотрите, что он делает. Люди могут делать то, о чём вы никогда бы не подумали, или делать что-то в другом порядке.
Проблемы с многопоточностью также являются очень частым источником ошибок, заставляющим седеть и орать на компьютер. Все рекомендации в пользу написания простого кода становятся на порядок важнее, когда система многопоточная. При поиске таких ошибок нельзя уверенно полагаться на отладку и модульные тесты, поэтому простота проектирования имеет первостепенное значение.
Итак, прежде чем спешить обвинять компилятор, фреймворк или библиотеку вспомните совет Шерлока Холмса: «После того, как вы исключили невозможное, то всё, что осталось, независимо от того, насколько невероятным оно выглядит, является истиной», и отдавайте предпочтение именно ему, а не правилу Дирка Джентли: «После того, как вы исключили невероятное, всё, что осталось, независимо от того, насколько невозможным оно выглядит, является истиной».

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Allan Kelly
День трёхсотый. #ВопросыНаСобеседовании
Юбилейный день – самое время начать новый тред)))
Самые часто задаваемые вопросы на собеседовании по ASP.NET MVC
1. Что такое MVC (Model-View-Controller)?
Модель–представление–контроллер (MVC) - это паттерн архитектуры ПО для разделения данных приложения, пользовательского интерфейса и управляющей логики на три отдельных компонента: модель, представление и контроллер — таким образом, что модификация каждого компонента может осуществляться независимо. ASP.NET MVC - это фреймворк для создания веб-приложений с использованием паттерна MVC.
Модель реализует бизнес-логику приложения. Объекты модели хранят данные модели и зачастую взаимодействуют с базой данных.
Представление реализует отображение данных. Чаще всего представления создаются на основе данных модели.
Контроллер обрабатывает взаимодействие с пользователем (запросы пользователя к страницам, либо данные, введённые пользователем в форму представления), взаимодействует с моделью (запрашивает или обновляет данные) и возвращает ответ (данные в представлении).
Разделение MVC помогает управлять сложными приложениями, потому что вы можете сосредоточиться на одной области за раз. Например, работать с представлением, не трогая бизнес-логику. Это также облегчает тестирование приложения. Кроме того, различные разработчики могут работать над представлением, логикой контроллера или бизнес-логикой параллельно.

Источник: https://www.c-sharpcorner.com
День триста первый. #Оффтоп
Затарился книжечками, чтобы не скучать в новом году)))
День триста второй. #юмор
Далёкое будущее уже не такое далёкое)))
👍1
День триста третий. #BestPractices
Операторы Равенства
Далее обсуждаются перегрузки операторов равенства (operator== и operator!=).

ИЗБЕГАЙТЕ перегрузки одного из операторов равенства без перегрузки другого.
❗️ НЕОБХОДИМО убедиться, что Object.Equals и операторы равенства имеют одинаковую семантику и схожие характеристики производительности. Чаще всего это означает, что необходимо переопределить Object.Equals, когда операторы равенства перегружены.
ИЗБЕГАЙТЕ выброса исключений из операторов равенства. Например, возвращайте false, если один из аргументов имеет значение null, а не выбрасывайте NullReferenceException.

Операторы равенства в значимых типах
ИСПОЛЬЗУЙТЕ перегрузку операторов равенства для значимых типов, если имеет смысл сравнивать объекты этого типа. В большинстве языков программирования отсутствует стандартная реализация operator== для значимых типов.

Операторы равенства в ссылочных типах
ИЗБЕГАЙТЕ перегрузки операторов равенства в изменяемых ссылочных типах. Многие языки имеют встроенные операторы равенства для ссылочных типов. Встроенные операторы обычно проверяют на равенство ссылки на объекты, и многие разработчики удивляются, когда поведение по умолчанию изменяется на проверку равенства значений. Эта проблема менее актуальна для неизменяемых ссылочных типов, потому что для неизменяемых типов разница между ссылочным равенством и равенством значений менее принципиальна.
ИЗБЕГАЙТЕ перегрузки операторов равенства в ссылочных типах, если реализация будет значительно медленнее, чем реализация ссылочного равенства.

Источник: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/
День триста четвёртый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
10. Тщательно выбирайте инструменты

Современные приложения очень редко пишутся с чистого листа. Они собираются с использованием существующих инструментов - компонентов, библиотек и фреймворков - по ряду веских причин:
1. Приложения увеличиваются в размерах и сложности, а время, необходимое для их разработки, сокращается. Это позволяет лучше использовать время и интеллект разработчиков, если они смогут сконцентрироваться на написании большего количества кода бизнес-логики и меньшего количества кода инфраструктуры.
2. Широко используемые компоненты и структуры, вероятно, будут иметь меньше ошибок, чем разработанные самостоятельно.
3. В сети доступно много высококачественного бесплатного программного обеспечения, что означает более низкие затраты на разработку и большую вероятность поиска разработчиков с необходимым интересом и опытом.
4. Производство и обслуживание программного обеспечения - трудоёмкая работа, поэтому покупка готового решения может быть дешевле, чем разработка.

Тем не менее, выбор правильного набора инструментов для вашего приложения может быть сложной задачей, требующей обдумывания. Делая выбор, вы должны иметь в виду несколько вещей:
1. Различные инструменты могут полагаться на разные предположения о контексте их использования: окружающей инфраструктуре, модели управления, модели данных, протоколах связи и т.д. Это может привести к несоответствию архитектуры приложения и инструментов. Такое несоответствие приводит появлению костылей и обходных путей, которые сделают код более сложным, чем необходимо.
2. Различные инструменты имеют разные жизненные циклы, и обновление одного из них может стать чрезвычайно сложной и трудоемкой задачей, поскольку новые функциональные возможности, изменения дизайна или даже исправления ошибок могут привести к несовместимости с другими инструментами. Чем больше инструментов, тем острее может встать эта проблема.
3. Некоторые инструменты требуют небольшой настройки, часто с помощью одного или нескольких файлов конфигурации, что очень быстро может выйти из-под контроля. Приложение может выглядеть так, как если бы оно было написано из файлов конфигурации и нескольких странных строк кода на каком-то языке программирования. Сложность конфигурации делает приложение трудным в обслуживании и расширении.
4. Зависимость от поставщика наступает, когда ваш код активно использует продукты конкретного поставщика, что в конечном итоге накладывает ограничения на код в плане расширяемости, лёгкости изменения, производительности, стоимости сопровождения и т.д.
5. Если вы планируете использовать бесплатное программное обеспечение, вы можете обнаружить, что оно не так уж и бесплатно. Возможно, вам придётся купить коммерческую поддержку, которая не обязательно будет дешёвой. Условия лицензирования имеют значение даже для свободного ПО. Например, в некоторых компаниях недопустимо использовать ПО с бесплатной лицензией GNU из-за его вирусной природы. То есть разработанное с использованием его ПО должно распространяться с открытым исходным кодом.

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

Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Giovanni Asproni
День триста пятый. #Оффтоп
Нелёгкая судьба программиста занесла меня в окрестности Майами. Поэтому сегодня будет совсем оффтоп, т.к. из-за длинного перелёта пост написать не смог. В общем, всем доброго утра с берегов Атлантики.
День триста шестой. #МоиИнструменты
Качество кода. Начало
Улучшение кода может быть сложной задачей. Чем больше кодовая база, тем сложнее становится вручную находить и исправлять плохой код. Функции становятся более трудоемкими и рискованными для реализации, а ошибки возникают чаще. Стоимость обучения новых сотрудников также возрастает, потому что им требуется больше времени, чтобы понять, что делает код. Поиск путей улучшения качества кода крайне важен. Лучше всего учитывать качество кода изначально, но зачастую эта мысль приходит поздно. Однако плохо написанный код может со временем быть очищен.
Анализ кода и метрики являются отправной точкой для улучшения кодовой базы. Код - это данные, и есть инструменты его анализа. Однако в Visual Studio они практически отсутствуют, поэтому необходимы сторонние решения.
Что нужно знать о коде:
- объём кода
- соответствует ли он нашим стандартам кодирования
- наиболее подверженные ошибкам области кода
- какие части кода слишком сложны
- можно ли провести юнит-тестирование модуля
и так далее.

Resharper / Rider
JetBrains является лидером в области рефакторинга и анализа кода. Resharper помогает вам находить проблемный код и быстро его исправлять, в то время как Rider - это полноценная IDE, обладающая той же функциональностью. Resharper - самый популярный инструмент рефакторинга кода C#, который также анализирует HTML, XAML, JavaScript и многое другое.
Этот инструмент используется для получения метрик для проблемного кода. Вы можете просканировать один проект или всё решение. Это полезно, потому что помогает идентифицировать шаблоны в кодовой базе. Например, понять, что команда не знает о каких-то функциях C#, или что из раза в раз делает типичные ошибки.
Недостатком Resharper является то, что он раздувает IDE, добавляя пункты в меню и может нарушить обычную работу Visual Studio. Я отключаю его, когда не выполняю рефакторинг, и использую только тогда, когда пришло время очистить код. Некоторым нравится интерфейс Resharper, поэтому есть смысл приобрести IDE Rider и получить Resharper бесплатно.

NDepend
NDepend – фреймворк для анализа кода. Он имеет функционал, аналогичный Resharper, но более высокоуровневые инструменты. Его можно использовать как отдельное приложение или как расширение Visual Studio. Он также интегрируется с множеством других инструментов для предоставления дополнительной информации. Например, может интегрироваться с инструментами анализа покрытия кода тестами, такими как dotCover.
NDepend не просто анализирует ваш код. Он также измеряет изменение качества вашего кода с течением времени и показывает это на графике.
Кроме того, он может определить, какие типы в первую очередь подойдут для рефакторинга, исходя из срока технического долга.
Поначалу NDepend может показаться слишком сложным. Это комплексный инструмент, который требует некоторых усилий, чтобы понять его и подготовить ваше решение. Однако для крупных проектов он может предоставить то, чего не могут другие решения.

Автор: Christian Findlay
Источник:
https://christianfindlay.com/
День триста седьмой. #ВопросыНаСобеседовании
Самые часто задаваемые вопросы на собеседовании по ASP.NET MVC
2. Какие преимущества у MVC?

- Поддержка нескольких представлений
Благодаря отделению модели от представления пользовательский интерфейс может отображать несколько представлений одних и тех же данных одновременно.
- Простота изменений
Пользовательские интерфейсы, как правило, меняются чаще, чем бизнес-правила (цвета, шрифты, дизайн для разных видов устройств и т.п.). Поскольку модель не зависит от представления, добавление новых представлений в систему не влияет на модель. В результате область изменений ограничена представлением.
- Разделение Ответственности (Separation of Concerns - SoC)
Это одно из основных преимуществ ASP.NET MVC. Инфраструктура MVC обеспечивает четкое разделение пользовательского интерфейса, бизнес-логики, модели или данных.
- Больше контроля
Среда ASP.NET MVC обеспечивает больший контроль над HTML, JavaScript и CSS, чем традиционные веб-формы.
- Простота интеграции с Javascript фреймворками
MVC дает возможность лёгкой интеграции с Javascript библиотеками и фреймворками (например, jQuery, Angular и т.п.).
- Тестируемость
Фреймворк ASP.NET MVC обеспечивает лучшую тестируемость веб-приложения и хорошую поддержку для разработки на основе тестирования (TDD).
- Легковесность
Платформа ASP.NET MVC не использует View State и, таким образом, до некоторой степени снижает нагрузку на сеть.
- Полнота возможностей ASP.NET
Одним из ключевых преимуществ использования ASP.NET MVC является то, что он построен поверх платформы ASP.NET, и, следовательно, предоставляет доступ к большинству функций ASP.NET, таких как поставщики членства, ролей и т.д.

Источник: https://www.c-sharpcorner.com