День четыреста девяносто пятый.
Я недавно выкладывал ссылку на видео канала Raw Coding про Middleware, и в нашем чате посоветовали посмотреть другие их видео. На этот раз пост не про одно видео, а про целый плейлист ASP.NET Core - Authentication & Authorization Tutorial https://www.youtube.com/playlist?list=PLOeFnOV9YBa7dnrjpOG6lMpcyd7Wn7E8V
Подробнейший рассказ про аутентификацию и авторизацию в ASP.NET Core, чего, кстати, очень не хватает той же книге Фримена (там вся огромная система коротко и скомкано описана в паре глав).
Мне понравился подход автора. Обычно рассказ начинают с простой авторизации, потом переходят к ролям, а потом к заявкам (утверждениям, клеймам, объектам claim, - куча названий в разных источниках). На самом деле, тут можно понять путаницу в названиях, потому что одним словом перевести слово claim на русский невозможно. Наверное, утверждение, будет лучшим вариантом, хотя, я бы в контексте авторизации назвал это «притязанием» (предъявлением своих прав на что-нибудь). Если смотрели Игру Престолов, то там все постоянно спорили, у кого бОльшие притязания на трон (по праву рождения, по старшинству и т.п). Вот это именно claims – набор утверждений о пользователе, дающий или не дающий ему право на что-либо.
Так вот, автор начинает рассказ именно с описания утверждений: где они находятся в системе авторизации и как они выдаются той или иной службой авторизации (на примере бабушки, рассказывающей о том, что её внук хороший)) ). И, удивительно, но, если вот так «начать с конца», а не с ролей, как обычно, всё прекрасно встаёт на свои места:
1. приложение определяет политику,
2. политика содержит требования,
3. требования проверяют наличие необходимых утверждений/притязаний.
А при авторизации с помощью ролей, роль – это просто частный случай утверждения.
Дальше там и про OAuth, и про Identity Server, я пока до туда не дошёл)))
В общем, не пожалейте 14,5 часов (да, я посчитал общую продолжительность плейлиста) на просмотр. Оно того несомненно стоит.
Я недавно выкладывал ссылку на видео канала Raw Coding про Middleware, и в нашем чате посоветовали посмотреть другие их видео. На этот раз пост не про одно видео, а про целый плейлист ASP.NET Core - Authentication & Authorization Tutorial https://www.youtube.com/playlist?list=PLOeFnOV9YBa7dnrjpOG6lMpcyd7Wn7E8V
Подробнейший рассказ про аутентификацию и авторизацию в ASP.NET Core, чего, кстати, очень не хватает той же книге Фримена (там вся огромная система коротко и скомкано описана в паре глав).
Мне понравился подход автора. Обычно рассказ начинают с простой авторизации, потом переходят к ролям, а потом к заявкам (утверждениям, клеймам, объектам claim, - куча названий в разных источниках). На самом деле, тут можно понять путаницу в названиях, потому что одним словом перевести слово claim на русский невозможно. Наверное, утверждение, будет лучшим вариантом, хотя, я бы в контексте авторизации назвал это «притязанием» (предъявлением своих прав на что-нибудь). Если смотрели Игру Престолов, то там все постоянно спорили, у кого бОльшие притязания на трон (по праву рождения, по старшинству и т.п). Вот это именно claims – набор утверждений о пользователе, дающий или не дающий ему право на что-либо.
Так вот, автор начинает рассказ именно с описания утверждений: где они находятся в системе авторизации и как они выдаются той или иной службой авторизации (на примере бабушки, рассказывающей о том, что её внук хороший)) ). И, удивительно, но, если вот так «начать с конца», а не с ролей, как обычно, всё прекрасно встаёт на свои места:
1. приложение определяет политику,
2. политика содержит требования,
3. требования проверяют наличие необходимых утверждений/притязаний.
А при авторизации с помощью ролей, роль – это просто частный случай утверждения.
Дальше там и про OAuth, и про Identity Server, я пока до туда не дошёл)))
В общем, не пожалейте 14,5 часов (да, я посчитал общую продолжительность плейлиста) на просмотр. Оно того несомненно стоит.
День четыреста девяносто седьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
44. Знай Больше Двух Языков Программирования
Уже довольно давно известно, что уровень мастерства программиста прямо пропорционален количеству различных парадигм программирования, которыми он владеет. То есть не количеством тех, которые он знает или о которых слышал, а тех, которые действительно может использовать.
Любой программист начинает с изучения одного языка программирования. Этот язык оказывает доминирующее влияние на то, как программист видит разработку ПО. Независимо от того, сколько лет программист использует этот язык, если он остаётся в этом языке, он будет знать только этот язык и «думать» только на этом языке.
Программист, который изучает второй язык, будет испытывать трудности, особенно если этот язык имеет другую модель вычислений. C, Паскаль, Фортран - все имеют одну и ту же фундаментальную модель вычислений. Переключение с Фортрана на С не составит большого труда. Переход с C на C++ приводит к фундаментальным проблемам в понимании поведения программ. Переход с C++ на Haskell потребует ещё большего изменения взглядов и, как следствие, будет ещё более сложен. А переход от С к Prolog будет представлять сложности почти наверняка.
Мы можем перечислить ряд парадигм вычислений: процедурная, объектно-ориентированная, функциональная, логическая, потоков данных и т. д. Переход между этими парадигмами наиболее сложная задача для программиста.
Почему эти сложности хороши? Это связано с тем, как мы представляем себе реализацию алгоритмов, идиом и шаблонов, которые мы применяем. В основе мастерства лежит «перекрёстное опыление». Идиомы для решения проблем в одном языке, могут быть недоступны в другом. Попытка перенести идиомы с одного языка на другой учит нас как обоим языкам, так и способам решения проблемы.
«Перекрестное опыление» в программировании имеет огромную эффективность. Возможно, наиболее очевидным является всё более широкое использование декларативных выражений в системах, реализованных на императивных языках. Любой, кто разбирается в функциональном программировании, может легко применить декларативный подход даже при использовании языка, такого как C. Использование декларативных подходов обычно приводит к более коротким и более понятным программам. Например, C++, безусловно, принимает это во внимание благодаря поддержке обобщённого программирования, что требует декларативного способа выражения.
Вывод из всего этого такой: каждому программисту следует иметь хорошие навыки программирования по крайней мере в двух разных парадигмах, а в идеале во всех вышеупомянутых. Программисты всегда должны быть заинтересованы в изучении новых языков, желательно из незнакомой парадигмы. Даже если в их повседневной работе используется один язык, нельзя недооценивать рост профессионализма в использовании этого языка, когда человек может извлекать пользу из других парадигм. Работодатели должны принять это во внимание и предоставить возможность сотрудникам изучать языки, которые в настоящее время не используются в их системе, в качестве повышения квалификации в используемых языках.
При этом короткого курса недостаточно для изучения нового языка. Как правило, требуется несколько месяцев использования, чтобы получить надлежащие рабочие знания. Важным является именно изучение идиом использования, а не только синтаксиса и модели вычислений.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Russel Winder
97 Вещей, Которые Должен Знать Каждый Программист
44. Знай Больше Двух Языков Программирования
Уже довольно давно известно, что уровень мастерства программиста прямо пропорционален количеству различных парадигм программирования, которыми он владеет. То есть не количеством тех, которые он знает или о которых слышал, а тех, которые действительно может использовать.
Любой программист начинает с изучения одного языка программирования. Этот язык оказывает доминирующее влияние на то, как программист видит разработку ПО. Независимо от того, сколько лет программист использует этот язык, если он остаётся в этом языке, он будет знать только этот язык и «думать» только на этом языке.
Программист, который изучает второй язык, будет испытывать трудности, особенно если этот язык имеет другую модель вычислений. C, Паскаль, Фортран - все имеют одну и ту же фундаментальную модель вычислений. Переключение с Фортрана на С не составит большого труда. Переход с C на C++ приводит к фундаментальным проблемам в понимании поведения программ. Переход с C++ на Haskell потребует ещё большего изменения взглядов и, как следствие, будет ещё более сложен. А переход от С к Prolog будет представлять сложности почти наверняка.
Мы можем перечислить ряд парадигм вычислений: процедурная, объектно-ориентированная, функциональная, логическая, потоков данных и т. д. Переход между этими парадигмами наиболее сложная задача для программиста.
Почему эти сложности хороши? Это связано с тем, как мы представляем себе реализацию алгоритмов, идиом и шаблонов, которые мы применяем. В основе мастерства лежит «перекрёстное опыление». Идиомы для решения проблем в одном языке, могут быть недоступны в другом. Попытка перенести идиомы с одного языка на другой учит нас как обоим языкам, так и способам решения проблемы.
«Перекрестное опыление» в программировании имеет огромную эффективность. Возможно, наиболее очевидным является всё более широкое использование декларативных выражений в системах, реализованных на императивных языках. Любой, кто разбирается в функциональном программировании, может легко применить декларативный подход даже при использовании языка, такого как C. Использование декларативных подходов обычно приводит к более коротким и более понятным программам. Например, C++, безусловно, принимает это во внимание благодаря поддержке обобщённого программирования, что требует декларативного способа выражения.
Вывод из всего этого такой: каждому программисту следует иметь хорошие навыки программирования по крайней мере в двух разных парадигмах, а в идеале во всех вышеупомянутых. Программисты всегда должны быть заинтересованы в изучении новых языков, желательно из незнакомой парадигмы. Даже если в их повседневной работе используется один язык, нельзя недооценивать рост профессионализма в использовании этого языка, когда человек может извлекать пользу из других парадигм. Работодатели должны принять это во внимание и предоставить возможность сотрудникам изучать языки, которые в настоящее время не используются в их системе, в качестве повышения квалификации в используемых языках.
При этом короткого курса недостаточно для изучения нового языка. Как правило, требуется несколько месяцев использования, чтобы получить надлежащие рабочие знания. Важным является именно изучение идиом использования, а не только синтаксиса и модели вычислений.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Russel Winder
День четыреста девяносто восьмой. #ЗаметкиНаПолях
Dotnet User-Secrets
Посмотрите на этот код файла
Более опытный разработчик, вероятно, добавит файл
К счастью, эту проблему легко исправить. Не нужно делать дополнительных файлов
Используйте
Источник: https://levelup.gitconnected.com/never-store-secrets-in-appsettings-json-3a7404ea50d0
Dotnet User-Secrets
Посмотрите на этот код файла
appsettings.json
. Видите что-нибудь необычное?{Третья строка содержит секретную информацию, которую вы бы не хотели отправлять в открытый репозиторий кода. Но такой пример описан во многих книгах и руководствах по ASP.NET Core. Понятно, почему так происходит – это просто. Тем не менее, это огромная дыра в безопасности. Никогда не храните конфиденциальные данные в исходном коде.
"ConnectionStrings": {
"default": "Server=server;Database=MyDB;User ID=user;Password=password"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}
Более опытный разработчик, вероятно, добавит файл
appsettings.Development.json
, но ещё лучше будет включить его в .gitignore
. К счастью, эту проблему легко исправить. Не нужно делать дополнительных файлов
appsettings.SomeEnvironment.json
. Вместо этого просто используйте appsettings.json
по умолчанию в качестве шаблона для того, что требуется для работы приложения.Используйте
dotnet user-secrets
для безопасного хранения конфиденциальных данных. Уберём данные строки подключения из открытого доступа:"ConnectionStrings": {Теперь нужно определить место хранения конфиденциальной информации пользователя с помощью команды
"default": ""
}
dotnet user-secrets initЕё нужно выполнить из папки проекта. В результате появится строка:
Set UserSecretsId to '…' for MSBuild project <путь_к_проекту>А в файл
.csproj
добавится блок<UserSecretsId>…</UserSecretsId>После этого можно добавлять значения конфиденциальных данных с помощью команды:
dotnet user-secrets setПервым параметром будет путь к элементу файла конфигурации с разделителями двоеточиями, а вторым параметром – значение. Например, для строки подключения выше команда будет выглядеть так:
dotnet user-secrets set "ConnectionStrings:default"Теперь, несмотря на то, что в самом файле appsettings.json значение не указано, оно будет использоваться в проекте из секретного хранилища.
"Server=server;Database=MyDB;User ID=user;Password=password"
Источник: https://levelup.gitconnected.com/never-store-secrets-in-appsettings-json-3a7404ea50d0
День четыреста девяносто девятый.
Книга Адама Фримена «Entity Framework Core 2 для ASP.NET Core MVC»
Отзыв на ещё одну книгу Адама Фримена. Эта книга, можно сказать, приложение к «ASP.NET Core MVC 2», о которой я писал раньше. Несмотря на то, что по структуре обе книги схожи, и в обеих даже расписан пример приложения SportsStore, но читать их можно независимо. Да, поскольку Entity Framework рассматривается в контексте ASP.NET MVC, какие-то минимальные представления о системе иметь надо, но в принципе, можно обойтись и без этого - необходимый минимум описан.
Во-первых, всё, что было сказано про «ASP.NET Core MVC 2», справедливо и для этой книги: .Net Core 2.1, какая-то чуть более новая версия устаревшего bower для управления клиентскими библиотеками (см. решение в посте про «ASP.NET Core MVC 2»). Ну и «гениальный» перевод от «Диалектики». Не могу не поделиться парочкой перлов:
1. «Посадочная страница».
Имеется в виду «landing page» - целевая страница, хотя в контексте речь идёт просто про представление для главной страницы сайта.
2. «Применение инфраструктуры Entity Framework Core для сохранения и извлечения данных прямолинейно после того, как основные средства на месте».
Итак, дословно последняя фраза «… is straightforward once fixed assets in place». Сразу два устойчивых оборота в одном предложении. Понимаю, что сложно))) На русский это можно перевести как: «Применение инфраструктуры EF … не представляет проблем после настройки основных параметров». Но ребята из Диалектики, видимо, торопились или им просто лень было разбираться с тем, что выдал гугл-переводчик.
При всём этом, книга довольно полезна. Подробно объясняется, как EF создаёт миграции и объекты в БД, как переводит выражения C# в команды SQL, какие частые ошибки использования возникают нужно и как их избегать. Ну и конечно продвинутое использование EF: индексы, отношения, database first и т.п. Приложение SportsStore (если вы, как и я, создавали его по примеру книги «ASP.NET Core MVC 2») можно доработать примером из этой - он больше относится к административной части приложения. Кроме того, что мне очень понравилось, в конце каждой главы приводится список распространённых проблем с описанием их решения. Рассказано всё довольно подробно, иногда с повторами, что лично для меня, хорошо знающего SQL, чересчур, но новичкам наоборот будет проще разобраться.
Книга Адама Фримена «Entity Framework Core 2 для ASP.NET Core MVC»
Отзыв на ещё одну книгу Адама Фримена. Эта книга, можно сказать, приложение к «ASP.NET Core MVC 2», о которой я писал раньше. Несмотря на то, что по структуре обе книги схожи, и в обеих даже расписан пример приложения SportsStore, но читать их можно независимо. Да, поскольку Entity Framework рассматривается в контексте ASP.NET MVC, какие-то минимальные представления о системе иметь надо, но в принципе, можно обойтись и без этого - необходимый минимум описан.
Во-первых, всё, что было сказано про «ASP.NET Core MVC 2», справедливо и для этой книги: .Net Core 2.1, какая-то чуть более новая версия устаревшего bower для управления клиентскими библиотеками (см. решение в посте про «ASP.NET Core MVC 2»). Ну и «гениальный» перевод от «Диалектики». Не могу не поделиться парочкой перлов:
1. «Посадочная страница».
Имеется в виду «landing page» - целевая страница, хотя в контексте речь идёт просто про представление для главной страницы сайта.
2. «Применение инфраструктуры Entity Framework Core для сохранения и извлечения данных прямолинейно после того, как основные средства на месте».
Итак, дословно последняя фраза «… is straightforward once fixed assets in place». Сразу два устойчивых оборота в одном предложении. Понимаю, что сложно))) На русский это можно перевести как: «Применение инфраструктуры EF … не представляет проблем после настройки основных параметров». Но ребята из Диалектики, видимо, торопились или им просто лень было разбираться с тем, что выдал гугл-переводчик.
При всём этом, книга довольно полезна. Подробно объясняется, как EF создаёт миграции и объекты в БД, как переводит выражения C# в команды SQL, какие частые ошибки использования возникают нужно и как их избегать. Ну и конечно продвинутое использование EF: индексы, отношения, database first и т.п. Приложение SportsStore (если вы, как и я, создавали его по примеру книги «ASP.NET Core MVC 2») можно доработать примером из этой - он больше относится к административной части приложения. Кроме того, что мне очень понравилось, в конце каждой главы приводится список распространённых проблем с описанием их решения. Рассказано всё довольно подробно, иногда с повторами, что лично для меня, хорошо знающего SQL, чересчур, но новичкам наоборот будет проще разобраться.
День пятисотый.
Вот и добрались мы с вами до небольшого юбилея. 500 дней подряд я выкладываю посты о том, что мне показалось интересным в мире изучения .NET. Большое спасибо, что читаете и огромное спасибо всем, кто комментирует, предлагает темы, исправляет неточности в постах.
В данный момент я продолжаю подготовку к экзамену 70-486 для получения сертификата MCSA: Web Applications, поэтому большая часть времени (помимо работы и подбора материала для постов) занята этим. Дальше я планирую поглубже окунуться в .NET5, Blazor и WebAssembly. Я недавно публиковал пост на эту тему.
У меня возникла одна идея, но прежде хочу узнать ваше мнение. Осенью выходит .NET5. Нет лучше способа опробовать его, чем практика. У меня есть идея создания полноценного веб приложения на .NET5, Blazor (возможно добавить API) и развёртывания в сервисах Azure (раз уж мы тут про Microsoft, то надо идти до конца))). Приложение будет касаться изучения .NET и программирования вообще. В двух словах – это организованный справочник источников для изучения программирования. Пока не буду вдаваться в детали, я сам ещё полноценную концепцию не продумал.
Собственно, поэтому у меня к вам такой вопрос. Есть ли среди моих подписчиков те, кому в образовательных целях было бы интересно поучаствовать в опенсорс проекте? Понимаю, что это звучит, типа, я ищу бесплатную рабочую силу. Но давайте объясню, как я это вижу. Мы как разработчики постоянно учимся. Это одно из требований профессии. Однако на работе не всегда удаётся учиться и практиковать то, что тебе интересно. Часто в корпоративных системах используются не самые новые версии языка и фреймворков. Часто отдельный разработчик отвечает только за что-то одно: написание модулей, тестирование, фронтенд, - и иногда эти области не пересекаются. Я предлагаю (только тем, кому это интересно) вместе создать приложение с нуля (продумывание функционала, проектирование подсистем, модулей, написание кода, тестов, CI/CD, вотэтовсё) на передовой на данный момент технологии. При этом каждый сможет заняться тем, что ему интересно, поделиться опытом или получить опыт в процессе. Никаких сроков, дедлайнов или обязаловок, всё исключительно по желанию и в свободное от основной деятельности время.
Да, понимаю, что звучит несколько утопично. В принципе, идея взята вот из этого совета. В общем, подумайте на досуге))) Подробности ближе к осени. А пока я хотел бы узнать, в принципе эта идея кому-нибудь интересна, и, если да, в чём вы можете поделиться опытом. Обсудить можем в чате.
Вот и добрались мы с вами до небольшого юбилея. 500 дней подряд я выкладываю посты о том, что мне показалось интересным в мире изучения .NET. Большое спасибо, что читаете и огромное спасибо всем, кто комментирует, предлагает темы, исправляет неточности в постах.
В данный момент я продолжаю подготовку к экзамену 70-486 для получения сертификата MCSA: Web Applications, поэтому большая часть времени (помимо работы и подбора материала для постов) занята этим. Дальше я планирую поглубже окунуться в .NET5, Blazor и WebAssembly. Я недавно публиковал пост на эту тему.
У меня возникла одна идея, но прежде хочу узнать ваше мнение. Осенью выходит .NET5. Нет лучше способа опробовать его, чем практика. У меня есть идея создания полноценного веб приложения на .NET5, Blazor (возможно добавить API) и развёртывания в сервисах Azure (раз уж мы тут про Microsoft, то надо идти до конца))). Приложение будет касаться изучения .NET и программирования вообще. В двух словах – это организованный справочник источников для изучения программирования. Пока не буду вдаваться в детали, я сам ещё полноценную концепцию не продумал.
Собственно, поэтому у меня к вам такой вопрос. Есть ли среди моих подписчиков те, кому в образовательных целях было бы интересно поучаствовать в опенсорс проекте? Понимаю, что это звучит, типа, я ищу бесплатную рабочую силу. Но давайте объясню, как я это вижу. Мы как разработчики постоянно учимся. Это одно из требований профессии. Однако на работе не всегда удаётся учиться и практиковать то, что тебе интересно. Часто в корпоративных системах используются не самые новые версии языка и фреймворков. Часто отдельный разработчик отвечает только за что-то одно: написание модулей, тестирование, фронтенд, - и иногда эти области не пересекаются. Я предлагаю (только тем, кому это интересно) вместе создать приложение с нуля (продумывание функционала, проектирование подсистем, модулей, написание кода, тестов, CI/CD, вотэтовсё) на передовой на данный момент технологии. При этом каждый сможет заняться тем, что ему интересно, поделиться опытом или получить опыт в процессе. Никаких сроков, дедлайнов или обязаловок, всё исключительно по желанию и в свободное от основной деятельности время.
Да, понимаю, что звучит несколько утопично. В принципе, идея взята вот из этого совета. В общем, подумайте на досуге))) Подробности ближе к осени. А пока я хотел бы узнать, в принципе эта идея кому-нибудь интересна, и, если да, в чём вы можете поделиться опытом. Обсудить можем в чате.
Интересна ли вам идея учебного проекта и в какой области вы можете поделиться опытом (выберите наиболее интересную вам):
Anonymous Poll
26%
Да, проектирование
41%
Да, написание кода
4%
Да, написание тестов
3%
Да, разработка UI
14%
Да, создание API
2%
Да, развёртывание
1%
Да, управление проектом
9%
Не интересно
День пятьсот первый. #MoreEffectiveCSharp
13. Предпочитайте Реализацию Интерфейсов Наследованию
Абстрактные базовые классы предоставляют общего предка для иерархии классов. Интерфейс описывает группу связанных методов, содержащих функционал, который должен быть реализован типом. У каждого подхода своё применение, и они не взаимозаменяемы. Интерфейсы - это способ объявления контракта. Абстрактные базовые классы предоставляют общую абстракцию для набора связанных типов. Наследование означает «является» (описывает, что такое объект), а интерфейс означает «ведёт себя как» (описание одного из поведений объекта).
Особенности интерфейсов:
1. Определяют многократно используемое поведение.
2. Могут быть параметром или возвращаемым значением.
3. Могут быть реализованы несвязанными типами.
4. Другим разработчикам легче реализовать интерфейс, чем наследовать от созданного вами базового класса.
5. Вы не можете обеспечить реализацию методов в интерфейсе. Однако можно создать методы расширения для него. Они будут частью любого типа, который реализует интерфейс.
6. Добавление нового члена к интерфейсу сломает все классы, которые его реализуют. Каждый разработчик должен будет обновить тип, чтобы включить новый член. В C#8 в интерфейсе можно определить реализацию по умолчанию, но этот приём нужно использовать с осторожностью. Если вы обнаружите, что вам нужно добавить функциональность в интерфейс, создайте новый и наследуйте от существующего интерфейса.
Особенности абстрактных базовых классов:
- могут предоставлять некоторую реализацию для производных типов в дополнение к описанию общего поведения, обеспечивая общее повторное использование реализации.
- при добавлении нового метода в базовый класс, все производные классы автоматически и неявно обновляются.
Выбор между абстрактным базовым классом и интерфейсом - это вопрос о том, как лучше поддерживать абстракции с течением времени. Интерфейсы фиксированы, а базовые классы могут быть расширены.
Интерфейсы как параметры методов
Рассмотрим два метода:
Интерфейсы как возвращаемые значения
Допустим, ваш класс имеет открытый метод, который возвращает коллекцию объектов:
1. Если вы захотите изменить тип возвращаемого значения со списка на массив или сортированный список, это нарушит код, т.к. это изменит открытый интерфейс вашего класса. Такое изменение заставляет вас делать гораздо больше изменений в системе, чем необходимо: вам нужно будет поменять все места, где происходит обращение к этому методу.
2. Вторая проблема в том, что
Источник: Bill Wagner “More Effective C#”. – 2nd ed. Глава 14.
13. Предпочитайте Реализацию Интерфейсов Наследованию
Абстрактные базовые классы предоставляют общего предка для иерархии классов. Интерфейс описывает группу связанных методов, содержащих функционал, который должен быть реализован типом. У каждого подхода своё применение, и они не взаимозаменяемы. Интерфейсы - это способ объявления контракта. Абстрактные базовые классы предоставляют общую абстракцию для набора связанных типов. Наследование означает «является» (описывает, что такое объект), а интерфейс означает «ведёт себя как» (описание одного из поведений объекта).
Особенности интерфейсов:
1. Определяют многократно используемое поведение.
2. Могут быть параметром или возвращаемым значением.
3. Могут быть реализованы несвязанными типами.
4. Другим разработчикам легче реализовать интерфейс, чем наследовать от созданного вами базового класса.
5. Вы не можете обеспечить реализацию методов в интерфейсе. Однако можно создать методы расширения для него. Они будут частью любого типа, который реализует интерфейс.
6. Добавление нового члена к интерфейсу сломает все классы, которые его реализуют. Каждый разработчик должен будет обновить тип, чтобы включить новый член. В C#8 в интерфейсе можно определить реализацию по умолчанию, но этот приём нужно использовать с осторожностью. Если вы обнаружите, что вам нужно добавить функциональность в интерфейс, создайте новый и наследуйте от существующего интерфейса.
Особенности абстрактных базовых классов:
- могут предоставлять некоторую реализацию для производных типов в дополнение к описанию общего поведения, обеспечивая общее повторное использование реализации.
- при добавлении нового метода в базовый класс, все производные классы автоматически и неявно обновляются.
Выбор между абстрактным базовым классом и интерфейсом - это вопрос о том, как лучше поддерживать абстракции с течением времени. Интерфейсы фиксированы, а базовые классы могут быть расширены.
Интерфейсы как параметры методов
Рассмотрим два метода:
public static void Print<T>(IEnumerable<T> col) {Любой тип, который поддерживает
foreach (T o in col)
Console.WriteLine(o);
}
public static void Print(MyCollection col) {
foreach (var o in col)
Console.WriteLine(o);
}
IEnumerable<T>
(List<T>
, SortedList<T>
, любой массив и результаты любого запроса LINQ), может использовать первый метод. Второй метод гораздо менее пригоден для повторного использования. Использование интерфейсов в качестве типов параметров метода гораздо более универсально и намного проще для повторного использования.Интерфейсы как возвращаемые значения
Допустим, ваш класс имеет открытый метод, который возвращает коллекцию объектов:
public List<SomeClass> DataSequence => sequence;Это создаёт сразу две проблемы:
private List<SomeClass> sequence = new List<SomeClass>();
1. Если вы захотите изменить тип возвращаемого значения со списка на массив или сортированный список, это нарушит код, т.к. это изменит открытый интерфейс вашего класса. Такое изменение заставляет вас делать гораздо больше изменений в системе, чем необходимо: вам нужно будет поменять все места, где происходит обращение к этому методу.
2. Вторая проблема в том, что
List<T>
предоставляет множество методов для изменения содержащихся в нём данных. Клиенты вашего класса смогут удалять, изменять или даже заменять элементы списка. Почти наверняка вы этого не хотите. К счастью, вы можете ограничить их возможности, вернув вместо ссылки на некоторый внутренний объект интерфейс IEnumerable<SomeClass>
. Используя интерфейсы в качестве типа возвращаемого значения, вы можете выбирать, какие методы и свойства для работы с предоставляемыми данными вы хотите открыть для клиентов класса.Источник: Bill Wagner “More Effective C#”. – 2nd ed. Глава 14.
День пятьсот второй. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
45. Знай Свою IDE
В 1980-х наши среды разработки были, в лучшем случае, немногим полезнее, обычных текстовых редакторов. Подсветка синтаксиса, которую мы сейчас считаем само собой разумеющейся, была не всем доступной роскошью. Инструменты форматирования кода обычно были сторонними продуктами, которые нужно было запускать, чтобы исправить отступы. Отладчики были также отдельными программами, запускаемыми для пошагового выполнения кода со множеством загадочных нажатий клавиш.
В 1990-х компании начали осознавать потенциальную пользу, которую они могли бы извлечь, предоставляя программистам лучшие и более полезные инструменты. Интегрированная среда разработки (IDE) объединила функции редактирования кода с компилятором, отладчиком, инструментами форматирования и другими полезными функциями. К тому времени выпадающие меню и мышь также стали популярными, что означало, что разработчикам больше не нужно было изучать загадочные комбинации клавиш, чтобы использовать редактор. Они могли просто выбрать команду из меню.
В 21-м веке IDE стали настолько обычным явлением, что их бесплатно раздают компании, желающие получить долю рынка в других областях. Современная IDE оснащена удивительным набором функций. Мой любимый инструмент - автоматический рефакторинг, особенно извлечение в метод, когда я могу выделить часть кода и преобразовывать его в метод. Инструмент рефакторинга подберёт все параметры, которые необходимо передать, что делает его использование чрезвычайно простым. IDE даже обнаружит другие похожие фрагменты кода, которые также могут быть заменены этим методом, и спросит меня, не хочу ли я их заменить.
Еще одна удивительная особенность современных IDE - возможность применять правила корпоративного стиля. Табы или пробелы, открывающая фигурная скобка в конце объявления или на новой строке… Каков бы ни был принятый стиль в компании, всё, что мне нужно сделать, чтобы следовать ему, это настроить его в моей IDE. Правила стиля также могут использоваться для поиска возможных ошибок.
К сожалению, современные IDE не требуют от нас усилий, чтобы научиться их использовать. Когда я впервые программировал в C на Unix, мне пришлось потратить немало времени на изучение работы редактора vi. Это потраченное время окупилось за годы использования. Я даже набираю черновик этой статьи с помощью vi. Современные IDE имеют очень плавную кривую обучения, что может привести к тому, что мы никогда не выйдем за рамки самого простого использования инструмента.
Мой первый шаг в изучении IDE - запоминание сочетаний клавиш. Так как мои пальцы находятся на клавиатуре, когда я набираю код, нажатие сочетания клавиш не прерывает хода работы, тогда использование мыши заставляет отвлечься, найти мышь, навести курсор, найти нужный пункт меню… Эти отвлечения приводят к ненужным переключениям контекста, снижая производительность. То же правило относится и к навыкам печатания: научитесь слепой печати - вы не пожалеете о потраченном времени. Наконец, у нас много инструментов манипуляции кодом: инструменты рефакторинга, поиска и замены по шаблону, и т.п.
Мы ожидаем, что сантехник, приходящий в наш дом, сможет использовать свой разводной ключ и отвёртки, и знает, как с ними обращаться. Давайте потратим немного времени на изучение того, как повысить эффективность в нашей IDE.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Heinz Kabutz
97 Вещей, Которые Должен Знать Каждый Программист
45. Знай Свою IDE
В 1980-х наши среды разработки были, в лучшем случае, немногим полезнее, обычных текстовых редакторов. Подсветка синтаксиса, которую мы сейчас считаем само собой разумеющейся, была не всем доступной роскошью. Инструменты форматирования кода обычно были сторонними продуктами, которые нужно было запускать, чтобы исправить отступы. Отладчики были также отдельными программами, запускаемыми для пошагового выполнения кода со множеством загадочных нажатий клавиш.
В 1990-х компании начали осознавать потенциальную пользу, которую они могли бы извлечь, предоставляя программистам лучшие и более полезные инструменты. Интегрированная среда разработки (IDE) объединила функции редактирования кода с компилятором, отладчиком, инструментами форматирования и другими полезными функциями. К тому времени выпадающие меню и мышь также стали популярными, что означало, что разработчикам больше не нужно было изучать загадочные комбинации клавиш, чтобы использовать редактор. Они могли просто выбрать команду из меню.
В 21-м веке IDE стали настолько обычным явлением, что их бесплатно раздают компании, желающие получить долю рынка в других областях. Современная IDE оснащена удивительным набором функций. Мой любимый инструмент - автоматический рефакторинг, особенно извлечение в метод, когда я могу выделить часть кода и преобразовывать его в метод. Инструмент рефакторинга подберёт все параметры, которые необходимо передать, что делает его использование чрезвычайно простым. IDE даже обнаружит другие похожие фрагменты кода, которые также могут быть заменены этим методом, и спросит меня, не хочу ли я их заменить.
Еще одна удивительная особенность современных IDE - возможность применять правила корпоративного стиля. Табы или пробелы, открывающая фигурная скобка в конце объявления или на новой строке… Каков бы ни был принятый стиль в компании, всё, что мне нужно сделать, чтобы следовать ему, это настроить его в моей IDE. Правила стиля также могут использоваться для поиска возможных ошибок.
К сожалению, современные IDE не требуют от нас усилий, чтобы научиться их использовать. Когда я впервые программировал в C на Unix, мне пришлось потратить немало времени на изучение работы редактора vi. Это потраченное время окупилось за годы использования. Я даже набираю черновик этой статьи с помощью vi. Современные IDE имеют очень плавную кривую обучения, что может привести к тому, что мы никогда не выйдем за рамки самого простого использования инструмента.
Мой первый шаг в изучении IDE - запоминание сочетаний клавиш. Так как мои пальцы находятся на клавиатуре, когда я набираю код, нажатие сочетания клавиш не прерывает хода работы, тогда использование мыши заставляет отвлечься, найти мышь, навести курсор, найти нужный пункт меню… Эти отвлечения приводят к ненужным переключениям контекста, снижая производительность. То же правило относится и к навыкам печатания: научитесь слепой печати - вы не пожалеете о потраченном времени. Наконец, у нас много инструментов манипуляции кодом: инструменты рефакторинга, поиска и замены по шаблону, и т.п.
Мы ожидаем, что сантехник, приходящий в наш дом, сможет использовать свой разводной ключ и отвёртки, и знает, как с ними обращаться. Давайте потратим немного времени на изучение того, как повысить эффективность в нашей IDE.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Heinz Kabutz
День пятьсот третий. #ЧтоНовенького
В Microsoft объявили о выходе .NET 5.0 Preview 5. Эта предварительная версия описана как «небольшой набор новых функций и улучшений производительности», так как большая часть функционала, запланированного под .NET 5, была выпущена в Preview 4 в прошлом месяце. Из особенностей Preview 5 можно выделить обновления в ASP.NET и Entity Framework.
В ASP.NET Core:
- Обновляемые конечные точки в конфигурации Kestrel
Kestrel теперь имеет возможность отслеживать изменения в конфигурации, передаваемой через
В Entity Framework Core 5.0
1. Параметры сортировки (collations) базы данных
Параметры сортировки теперь можно указать в модели EF, и они будут указаны в миграции.
- Для всей базы данных:
Теперь из командной строки в метод
3. Сохраняемые вычисляемые столбцы
Большинство баз данных позволяют хранить вычисляемые значения в столбцах. Хотя это занимает место на диске, вычисляемый столбец вычисляется только один раз при обновлении, а не каждый раз, когда извлекается его значение. Это также позволяет индексировать столбец в некоторых базах данных. EF Core 5.0 позволяет конфигурировать вычисляемые столбцы как сохраняемые:
Запросы без отслеживания теперь можно настроить для разрешения идентификатора. Например, следующий запрос создаст новый экземпляр
Источники:
- https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-5-preview-5/
- https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-5-0-preview-5/
В Microsoft объявили о выходе .NET 5.0 Preview 5. Эта предварительная версия описана как «небольшой набор новых функций и улучшений производительности», так как большая часть функционала, запланированного под .NET 5, была выпущена в Preview 4 в прошлом месяце. Из особенностей Preview 5 можно выделить обновления в ASP.NET и Entity Framework.
В ASP.NET Core:
- Обновляемые конечные точки в конфигурации Kestrel
Kestrel теперь имеет возможность отслеживать изменения в конфигурации, передаваемой через
KestrelServerOptions.Configure
и применять изменения к конечным точкам без необходимости перезапуска приложения.В Entity Framework Core 5.0
1. Параметры сортировки (collations) базы данных
Параметры сортировки теперь можно указать в модели EF, и они будут указаны в миграции.
- Для всей базы данных:
modelBuilder.UseCollation("German_PhoneBook_CI_AS");Это приведёт к следующему коду для SQL Server:
CREATE DATABASE [Test]- Для отдельных столбцов:
COLLATE German_PhoneBook_CI_AS;
modelBuilder-
.Entity<User>()
.Property(e => e.Name)
.UseCollation("German_PhoneBook_CI_AS");
EF.Functions.Collate
для отдельных запросов (с осторожностью, т.к. это может негативно сказаться на производительности):context.Users.Single(e => EF.Functions.Collate(e.Name, "French_CI_AS") == "Jean-Michel Jarre");2. Аргументы управления потоком в IDesignTimeDbContextFactory
Теперь из командной строки в метод
CreateDbContext
объекта IDesignTimeDbContextFactory
можно передавать пользовательские аргументы. Например, указать, что сборка для разработки, в командной строке можно передать пользовательский аргумент (например, dev
):dotnet ef migrations add two --verbose --devЭтот аргумент затем поступит в фабрику, где он может быть использован для управления созданием и инициализацией контекста.
3. Сохраняемые вычисляемые столбцы
Большинство баз данных позволяют хранить вычисляемые значения в столбцах. Хотя это занимает место на диске, вычисляемый столбец вычисляется только один раз при обновлении, а не каждый раз, когда извлекается его значение. Это также позволяет индексировать столбец в некоторых базах данных. EF Core 5.0 позволяет конфигурировать вычисляемые столбцы как сохраняемые:
modelBuilder4. Запросы без отслеживания с разрешением идентификатора
.Entity<User>()
.Property(e => e.SomethingComputed)
.HasComputedColumnSql("my sql", stored: true);
Запросы без отслеживания теперь можно настроить для разрешения идентификатора. Например, следующий запрос создаст новый экземпляр
Blog
для каждой записи из Posts
, даже при том, что экземпляры будут иметь одинаковые первичные ключи:context.Posts.AsNoTracking().Include(e => e.Blog).ToList();Этот запрос можно изменить, чтобы обеспечить создание только одного экземпляра
Blog
:context.Posts.AsNoTracking().PerformIdentityResolution().Include(e => e.Blog).ToList();Обратите внимание, что это полезно только для запросов без отслеживания (
AsNoTracking
).Источники:
- https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-5-preview-5/
- https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-5-0-preview-5/
День пятьсот пятый. #ЧтоНовенького
Официально выпущен gRPC-Web для .NET
gRPC - это современная высокопроизводительная среда Удаленного Вызова Процедур (RPC). gRPC основан на HTTP/2, Protocol Buffers и других современных стандартах. gRPC является открытым стандартом и поддерживается многими языками программирования, включая .NET.
В настоящее время невозможно реализовать спецификацию gRPC HTTP/2 в браузере, поскольку не существует API браузера с достаточным детальным контролем над запросами. gRPC-Web - это стандартизированный протокол, который решает эту проблему и позволяет использовать gRPC в браузере. gRPC-Web привносит многие современные функции gRPC, такие как небольшие двоичные сообщения и API Contract First, в современные приложения для браузеров.
Новые возможности с gRPC-Web
gRPC-Web разработан, чтобы сделать gRPC доступным в большем количестве сценариев. К ним относятся:
1. Вызов приложений ASP.NET Core gRPC из браузера - API браузера не могут вызывать gRPC HTTP/2. gRPC-Web предлагает совместимую альтернативу:
- JavaScript SPA
- Приложения .NET Blazor Web Assembly
2. Размещение приложений ASP.NET Core gRPC в IIS и Службе Приложений Azure - Некоторые серверы, такие как IIS и Служба Приложений Azure, в настоящее время не могут размещать службы gRPC. Пока над этим активно работают, gRPC-Web предлагает альтернативу, которая сегодня работает в любой среде.
3. Вызовы gRPC с платформ, отличных от .NET Core - HttpClient не поддерживает HTTP/2 на платформах .NET. gRPC-Web может использоваться для вызова сервисов gRPC из Blazor и Xamarin.
gRPC-Web – это комплексное решение для разработчиков при использовании в приложениях Blazor WebAssembly. Инструментарий gRPC не только автоматически генерирует строго типизированные клиенты для вызова служб gRPC из приложений Blazor, но и предлагает значительные преимущества в производительности по сравнению с JSON. Повышение производительности происходит благодаря эффективной двоичной сериализации gRPC по сравнению с традиционным текстовым JSON.
Попробуйте gRPC-Web с ASP.NET Core
- Новичкам в gRPC подойдёт руководство «Создание Клиента и Сервера gRPC в ASP.NET Core».
- Для готовых приложений посмотрите статью «Использование gRPC в браузерных приложениях».
- Пример приложения, использующего gRPC-Web.
gRPC-Web для .NET доступна в NuGet пакетах:
-
-
Источник: https://devblogs.microsoft.com/aspnet/grpc-web-for-net-now-available/
Официально выпущен gRPC-Web для .NET
gRPC - это современная высокопроизводительная среда Удаленного Вызова Процедур (RPC). gRPC основан на HTTP/2, Protocol Buffers и других современных стандартах. gRPC является открытым стандартом и поддерживается многими языками программирования, включая .NET.
В настоящее время невозможно реализовать спецификацию gRPC HTTP/2 в браузере, поскольку не существует API браузера с достаточным детальным контролем над запросами. gRPC-Web - это стандартизированный протокол, который решает эту проблему и позволяет использовать gRPC в браузере. gRPC-Web привносит многие современные функции gRPC, такие как небольшие двоичные сообщения и API Contract First, в современные приложения для браузеров.
Новые возможности с gRPC-Web
gRPC-Web разработан, чтобы сделать gRPC доступным в большем количестве сценариев. К ним относятся:
1. Вызов приложений ASP.NET Core gRPC из браузера - API браузера не могут вызывать gRPC HTTP/2. gRPC-Web предлагает совместимую альтернативу:
- JavaScript SPA
- Приложения .NET Blazor Web Assembly
2. Размещение приложений ASP.NET Core gRPC в IIS и Службе Приложений Azure - Некоторые серверы, такие как IIS и Служба Приложений Azure, в настоящее время не могут размещать службы gRPC. Пока над этим активно работают, gRPC-Web предлагает альтернативу, которая сегодня работает в любой среде.
3. Вызовы gRPC с платформ, отличных от .NET Core - HttpClient не поддерживает HTTP/2 на платформах .NET. gRPC-Web может использоваться для вызова сервисов gRPC из Blazor и Xamarin.
gRPC-Web – это комплексное решение для разработчиков при использовании в приложениях Blazor WebAssembly. Инструментарий gRPC не только автоматически генерирует строго типизированные клиенты для вызова служб gRPC из приложений Blazor, но и предлагает значительные преимущества в производительности по сравнению с JSON. Повышение производительности происходит благодаря эффективной двоичной сериализации gRPC по сравнению с традиционным текстовым JSON.
Попробуйте gRPC-Web с ASP.NET Core
- Новичкам в gRPC подойдёт руководство «Создание Клиента и Сервера gRPC в ASP.NET Core».
- Для готовых приложений посмотрите статью «Использование gRPC в браузерных приложениях».
- Пример приложения, использующего gRPC-Web.
gRPC-Web для .NET доступна в NuGet пакетах:
-
Grpc.AspNetCore.Web
- добавляет поддержку gRPC-Web в службу ASP.NET Core gRPC.-
Grpc.Net.Client.Web
– позволяет осуществлять вызовы конечных точек gRPC-Web из .NET.Источник: https://devblogs.microsoft.com/aspnet/grpc-web-for-net-now-available/
День пятьсот шестой. #MoreEffectiveCSharp
Новый Паттерн для Логирования Исключений
Логируйте исключения из фильтра исключений, а не из блока catch.
Современные системы логирования поддерживают расширенные контекстные журналы. Вы можете добавлять поля данных в сообщения журнала, а затем использовать их при отладке. Например, отфильтровать журнал по диапазону кодов HTTP или показать только ошибки
Помимо этого, современные системы поддерживают области логирования (см. BeginScope), что позволяет добавлять дополнительную информацию к сообщению в лог из разных частей метода, которая будет записана при вызове метода записи в журнал.
Большинство методов не логгируют исключения, они выбрасывают их вверх по стеку, где исключение регистрируется на более высоком уровне. Проблема этого подхода заключается в том, что область логгирования теряется после разворачивания стека:
Решение
Фильтры исключений выполняется там, где выбрасывается исключение, а не там, где оно перехватывается. Это происходит до разворачивания стека, поэтому область логирования сохраняется.
Фильтр исключений должен возвращать булево значение, указывающее, подходит ли блок
1.
Новый Паттерн для Логирования Исключений
Логируйте исключения из фильтра исключений, а не из блока catch.
Современные системы логирования поддерживают расширенные контекстные журналы. Вы можете добавлять поля данных в сообщения журнала, а затем использовать их при отладке. Например, отфильтровать журнал по диапазону кодов HTTP или показать только ошибки
FileNotFound
у пользователя Steve
.Помимо этого, современные системы поддерживают области логирования (см. BeginScope), что позволяет добавлять дополнительную информацию к сообщению в лог из разных частей метода, которая будет записана при вызове метода записи в журнал.
Большинство методов не логгируют исключения, они выбрасывают их вверх по стеку, где исключение регистрируется на более высоком уровне. Проблема этого подхода заключается в том, что область логгирования теряется после разворачивания стека:
try {
MyMethod();
}
catch (Exception e) {
logger.LogError(e, "");
…
}
Когда генерируется исключение, среда выполнения будет искать в стеке соответствующий обработчик. Cтек разворачивается до найденной точки и выполняется блок catch
. Таким образом, дополнительная информация в области логирования, добавленная в методе MyMethod
, будет потеряна при логировании исключения из блока catch
.Решение
Фильтры исключений выполняется там, где выбрасывается исключение, а не там, где оно перехватывается. Это происходит до разворачивания стека, поэтому область логирования сохраняется.
Фильтр исключений должен возвращать булево значение, указывающее, подходит ли блок
catch
под фильтр. В нашем случае логирование - просто побочный эффект, который не влияет на соответствие блока catch
фильтру. Определим два метода, возвращающие true
или false
в зависимости от того, нужно нам «проглотить» исключение, либо выбросить его выше по стеку:1.
Rethrow
можно использовать, когда catch
не содержит ничего, кроме throw;
. В таком случае Rethrow
логгирует исключение, вернёт false, блок catch не выполнится, а среда выполнения продолжит искать обработчик выше по стеку:try {
MyMethod();
}
catch (Exception e) when
(Rethrow(()=>logger.LogError(e, ""))
{
throw;
}
public static bool Rethrow(Action action) {
action();
return false;
}
2. Другой сценарий, когда catch
обрабатывает исключение. В этом случае метод Handle
логирует исключение, вернёт true
, и исключение будет обработано в блоке catch
:try {
MyMethod();
}
catch (Exception e) when
(Handle(()=>logger.LogError(e, ""))
{
// обработка исключения
}
public static bool Handle(Action action) {
action();
return true;
}
Источник: https://blog.stephencleary.com/2020/06/a-new-pattern-for-exception-logging.htmlДень пятьсот седьмой. #CSharp9
C# 9: На Пути к Поддержке Сценариев
Одной из определяющих характеристик языков «сценариев» является то, что им не нужен шаблон. Самой первой строкой файла могут быть объявления и операторы. Тогда как в C# или Java требуется некоторый метод
Мэдс Торгерсен из Microsoft предлагает реализовать эту возможность в C# 9. Операторы и функции верхнего уровня можно будет не включать в метод
Компилятор C # в настоящее время понимает диалект языка, используемого для различных сценариев и интерактивных целей. На этом диалекте операторы могут быть написаны на верхнем уровне (без включения в тело методов), а невиртуальные члены могут быть написаны на верхнем уровне (без включения в объявление типа).
В настоящее время версия C# для сценариев используется не очень интенсивно, но Торгерсен предсказывает, что это изменится в будущем: «Помимо Try.NET, сценарии также набирают популярность в обработке данных и машинном обучении, и там сценарные языки выигрывают от непосредственного режима работы с живыми данными.»
Есть несколько сценариев реализации этого функционала, наиболее вероятный из которых следующий. Операторы будет разрешено размещать перед объявлением пространства имен. Любые такие операторы будут скомпилированы в функцию
Содержимое операторов будет определять, как будет выглядеть сгенерированный код. Существует четыре возможности в зависимости от того, используется ли
Другой сценарий. Функции могут быть объявлены в пространстве имен или глобально. По умолчанию они будут
Источник: https://www.infoq.com/news/2020/05/CSharp-9-Scripting/
C# 9: На Пути к Поддержке Сценариев
Одной из определяющих характеристик языков «сценариев» является то, что им не нужен шаблон. Самой первой строкой файла могут быть объявления и операторы. Тогда как в C# или Java требуется некоторый метод
Main
, содержащийся внутри класса.Мэдс Торгерсен из Microsoft предлагает реализовать эту возможность в C# 9. Операторы и функции верхнего уровня можно будет не включать в метод
Main
класса Program
.Компилятор C # в настоящее время понимает диалект языка, используемого для различных сценариев и интерактивных целей. На этом диалекте операторы могут быть написаны на верхнем уровне (без включения в тело методов), а невиртуальные члены могут быть написаны на верхнем уровне (без включения в объявление типа).
В настоящее время версия C# для сценариев используется не очень интенсивно, но Торгерсен предсказывает, что это изменится в будущем: «Помимо Try.NET, сценарии также набирают популярность в обработке данных и машинном обучении, и там сценарные языки выигрывают от непосредственного режима работы с живыми данными.»
Есть несколько сценариев реализации этого функционала, наиболее вероятный из которых следующий. Операторы будет разрешено размещать перед объявлением пространства имен. Любые такие операторы будут скомпилированы в функцию
Main
класса Program
. Эта функция будет поддерживать асинхронные операции. Если несколько файлов имеют исполняемые операторы вне пространства имен, произойдет ошибка компилятора. Содержимое операторов будет определять, как будет выглядеть сгенерированный код. Существует четыре возможности в зависимости от того, используется ли
await
или нет, и есть ли оператор return
:static void Main(string[] args)Локальные функции разрешены с использованием обычного синтаксиса.
static int Main(string[] args)
static Task Main(string[] args)
static Task<int> Main(string[] args)
Другой сценарий. Функции могут быть объявлены в пространстве имен или глобально. По умолчанию они будут
internal
, хотя public
также будет разрешён. Потребители увидят, что функция принадлежит непосредственно к пространству имен. Реализовано это будет через частичный класс, оборачивающий элементы как статические члены. Если какой-либо из членов верхнего уровня будет public
, то и класс будет public
и помечен таким образом, чтобы потребляющая сборка знала, что к членам этого класса можно будет обращаться напрямую.Источник: https://www.infoq.com/news/2020/05/CSharp-9-Scripting/
День пятьсот восьмой. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
46. Знайте Свои Пределы
Ваши ресурсы ограничены. У вас есть только определённое количество времени и денег, чтобы выполнять свою работу, включая время и деньги, необходимые для обновления ваших знаний, навыков и инструментов. Вы можете работать только с определённым усердием, скоростью и не бесконечно. Ваши инструменты ограничены по мощности. Машины ваших пользователей тем более ограничены по мощности. Таким образом, вы должны знать ограничения своих ресурсов.
Как соблюдать эти ограничения? Знайте свои способности, знайте способности коллег, знайте свой бюджет и знайте свои инструменты. Особенно, как инженер-программист, вы должны знать пространственно-временную сложность ваших структур данных и алгоритмов, а также архитектуру и характеристики производительности ваших систем. Ваша задача - создать оптимальное сочетание программного обеспечения и систем.
Пространственно-временная сложность задается как функция
Анализ сложности измеряется в терминах абстрактной машины, но программное обеспечение работает на реальных машинах. Современные компьютерные системы организованы в виде иерархий физических и виртуальных машин, включая языковые среды выполнения, операционные системы, процессоры, кэш-память, оперативную память, диски и сети.
Ёмкость и скорость обращения к различным хранилищам варьируются на несколько порядков. Кэширование и последовательный доступ интенсивно используются на каждом уровне наших систем, чтобы скрыть эту разницу, но они работают только тогда, когда доступ предсказуем. При частых «промахах кэша» система будет тормозить. Например, чтобы в случайном порядке прочитать все байты жесткого диска, может понадобиться 32 года. А чтобы случайно просмотреть всю оперативную память – 11 минут. Случайный доступ непредсказуем. Исходя из этого, следует помнить, что повторный доступ к уже использовавшимся элементам и последовательный доступ практически всегда работают эффективно.
Алгоритмы и структуры данных различаются по тому, насколько эффективно они используют кэш. Например:
- Линейный поиск хорошо использует последовательный доступ, но требует
- Двоичный поиск отсортированного массива требует только
- Поиск по дереву van Emde Boas также требует
Как выбрать? Только измеряя. Линейный поиск наиболее выгоден для небольших массивов, однако существенно проигрывает при увеличении размера. Алгоритм van Emde Boas выигрывает благодаря предсказуемому доступу к данным.
Источники:
- https://www.oreilly.com/library/view/97-things-every/9780596809515/ Автор оригинала – Greg Colvin
- https://habr.com/ru/post/188010/
97 Вещей, Которые Должен Знать Каждый Программист
46. Знайте Свои Пределы
Ваши ресурсы ограничены. У вас есть только определённое количество времени и денег, чтобы выполнять свою работу, включая время и деньги, необходимые для обновления ваших знаний, навыков и инструментов. Вы можете работать только с определённым усердием, скоростью и не бесконечно. Ваши инструменты ограничены по мощности. Машины ваших пользователей тем более ограничены по мощности. Таким образом, вы должны знать ограничения своих ресурсов.
Как соблюдать эти ограничения? Знайте свои способности, знайте способности коллег, знайте свой бюджет и знайте свои инструменты. Особенно, как инженер-программист, вы должны знать пространственно-временную сложность ваших структур данных и алгоритмов, а также архитектуру и характеристики производительности ваших систем. Ваша задача - создать оптимальное сочетание программного обеспечения и систем.
Пространственно-временная сложность задается как функция
O(f(n))
, которая для n
, определяющего объём входных данных, определяет объём затрачиваемых пространства или времени, при росте n
. Основные уровни сложности для f(n)
включают 1
, log(n)
, n
, nlog(n)
, n^2
, 2^n
и n!
. Как видно из графика этих функций ниже, при росте n
: O(log(n))
растёт намного медленнее, чем O(n)
или O(nlog(n))
, а они - намного медленнее, чем O(n^2)
или O(2^n)
. Как говорит Шон Перент, для доступных значений n
можно выделить три класса сложности: константная, линейная и бесконечная.Анализ сложности измеряется в терминах абстрактной машины, но программное обеспечение работает на реальных машинах. Современные компьютерные системы организованы в виде иерархий физических и виртуальных машин, включая языковые среды выполнения, операционные системы, процессоры, кэш-память, оперативную память, диски и сети.
Ёмкость и скорость обращения к различным хранилищам варьируются на несколько порядков. Кэширование и последовательный доступ интенсивно используются на каждом уровне наших систем, чтобы скрыть эту разницу, но они работают только тогда, когда доступ предсказуем. При частых «промахах кэша» система будет тормозить. Например, чтобы в случайном порядке прочитать все байты жесткого диска, может понадобиться 32 года. А чтобы случайно просмотреть всю оперативную память – 11 минут. Случайный доступ непредсказуем. Исходя из этого, следует помнить, что повторный доступ к уже использовавшимся элементам и последовательный доступ практически всегда работают эффективно.
Алгоритмы и структуры данных различаются по тому, насколько эффективно они используют кэш. Например:
- Линейный поиск хорошо использует последовательный доступ, но требует
O(n)
сравнений.- Двоичный поиск отсортированного массива требует только
O(log(n))
сравнений.- Поиск по дереву van Emde Boas также требует
O(log(n))
сравнений и при этом эффективно использует кэш.Как выбрать? Только измеряя. Линейный поиск наиболее выгоден для небольших массивов, однако существенно проигрывает при увеличении размера. Алгоритм van Emde Boas выигрывает благодаря предсказуемому доступу к данным.
Источники:
- https://www.oreilly.com/library/view/97-things-every/9780596809515/ Автор оригинала – Greg Colvin
- https://habr.com/ru/post/188010/
День пятьсот девятый. #CSharp9
C# 9: Улучшения Частичных Методов для Генераторов Кода
Генераторы исходного кода в C# 9 позволят расширениям компилятора проверять код, а затем вводить дополнительный исходный код во время компиляции. Этот внедрённый код затем включается в ту же компилируемую сборку. Чтобы упростить эту возможность, Microsoft снимает большинство ограничений с частичных методов.
Частичные методы были введены в 2007 году, чтобы расширить возможности генераторов исходного кода. Основная идея в том, что в сгенерированном коде есть заглушки в виде частичных методов. Если разработчик хочет изменить поведение кода, то он может реализовать частичный метод. В противном случае частичный метод, как и любые его вызовы, удаляются.
Теперь поведение изменено. Разработчик определяет, какие частичные методы нужны. Затем генератор исходного кода видит и реализует их, используя комбинацию внешней информации и информации об окружении. Например, генератор исходного кода может комбинировать атрибуты частичного метода со схемой базы данных для генерации SQL кода запроса.
В настоящее время частичные методы имеют несколько ограничений:
- должны возвращать void,
- могут иметь параметры in или ref, но не out,
- неявно являются закрытыми, и поэтому не могут быть виртуальными,
Согласно предложению о расширении частичных методов, эти ограничения будут сняты. Причина этого изменения объясняется так: «Это расширило бы набор сценариев использования генераторов кода, в которых могли бы участвовать частичные методы. Например, регулярное выражение может быть определено с использованием следующего шаблона:
При этом получится вторая категория частичных методов, которые не будут удаляться из кода, но не будут ограничены в том, что вы можете с ними делать. Чтобы различать две категории, предлагается два основных правила:
1. Если
2. Если
Чисто технически эта новая категория частичных методов представляет собой абстрактные методы, потому что они должны быть реализованы. Но поскольку такие методы не обязательно являются виртуальными, в Microsoft решили, что перепрофилирование ключевого слова
Другие члены класса, такие как частичные свойства, частичные конструкторы и частичные операторы, находятся на рассмотрении для C# 10. Поскольку они не являются строго необходимыми для расширения возможностей генераторов кода, вводить их в C# 9 не является критически важным.
Источник: https://www.infoq.com/news/2020/06/CSharp-9-Partial-Methods/
C# 9: Улучшения Частичных Методов для Генераторов Кода
Генераторы исходного кода в C# 9 позволят расширениям компилятора проверять код, а затем вводить дополнительный исходный код во время компиляции. Этот внедрённый код затем включается в ту же компилируемую сборку. Чтобы упростить эту возможность, Microsoft снимает большинство ограничений с частичных методов.
Частичные методы были введены в 2007 году, чтобы расширить возможности генераторов исходного кода. Основная идея в том, что в сгенерированном коде есть заглушки в виде частичных методов. Если разработчик хочет изменить поведение кода, то он может реализовать частичный метод. В противном случае частичный метод, как и любые его вызовы, удаляются.
Теперь поведение изменено. Разработчик определяет, какие частичные методы нужны. Затем генератор исходного кода видит и реализует их, используя комбинацию внешней информации и информации об окружении. Например, генератор исходного кода может комбинировать атрибуты частичного метода со схемой базы данных для генерации SQL кода запроса.
В настоящее время частичные методы имеют несколько ограничений:
- должны возвращать void,
- могут иметь параметры in или ref, но не out,
- неявно являются закрытыми, и поэтому не могут быть виртуальными,
Согласно предложению о расширении частичных методов, эти ограничения будут сняты. Причина этого изменения объясняется так: «Это расширило бы набор сценариев использования генераторов кода, в которых могли бы участвовать частичные методы. Например, регулярное выражение может быть определено с использованием следующего шаблона:
[RegexGenerated("(dog|cat|fish)")]Это даёт разработчику простой декларативный способ использования генераторов кода, а генераторам очень простой набор инструкций для генерации вывода.»
public partial bool IsPetMatch(string input);
При этом получится вторая категория частичных методов, которые не будут удаляться из кода, но не будут ограничены в том, что вы можете с ними делать. Чтобы различать две категории, предлагается два основных правила:
1. Если
partial
указан с явным модификатором доступа (public
, private
и т.д.), то метод должен быть реализован, может возвращать значения и может иметь параметры out
.2. Если
partial
указан без явного модификатора доступа, то метод может быть удалён из кода, должен возвращать void
и не может иметь out
параметров.Чисто технически эта новая категория частичных методов представляет собой абстрактные методы, потому что они должны быть реализованы. Но поскольку такие методы не обязательно являются виртуальными, в Microsoft решили, что перепрофилирование ключевого слова
abstract
только внесёт лишнюю путаницу.Другие члены класса, такие как частичные свойства, частичные конструкторы и частичные операторы, находятся на рассмотрении для C# 10. Поскольку они не являются строго необходимыми для расширения возможностей генераторов кода, вводить их в C# 9 не является критически важным.
Источник: https://www.infoq.com/news/2020/06/CSharp-9-Partial-Methods/
День пятьсот десятый. #ЗаметкиНаПолях
Указатели в C#
Несмотря на то, что в C# 7 добавлены достаточно богатые возможности передачи типов значений по ссылке, иногда требуется использовать небезопасный код и канонические указатели.
Указатель - это переменная, которая содержит адрес хранения значения в памяти. В C# указатели могут быть объявлены только для типов значений.
Указатели объявляются с помощью символа «разыменования»
Оператор
Указатели могут быть объявлены для структур, как в следующем примере:
Основная проблема с использованием указателей в C# в том, что CLR управляет процессом сбора мусора в фоновом режиме. Освобождая память, сборка мусора может изменить расположение объекта без предупреждения и испортить указатель на него. Это может как поставить под угрозу работу программы, так и повлиять на целостность других программ. Из-за этих проблем использование указателей ограничено кодом, который программист явно помечает как «небезопасный» (
Чтобы решить эту проблему, можно объявить указатель в выражении
Указатель может быть объявлен для массива:
Указатели в C#
Несмотря на то, что в C# 7 добавлены достаточно богатые возможности передачи типов значений по ссылке, иногда требуется использовать небезопасный код и канонические указатели.
Указатель - это переменная, которая содержит адрес хранения значения в памяти. В C# указатели могут быть объявлены только для типов значений.
Указатели объявляются с помощью символа «разыменования»
*
:int *p;либо
int* p;Это объявление устанавливает в переменную p указатель на адрес начала целого числа в памяти (4 байта).
Оператор
&
возвращает адрес хранения переменной. В коде ниже p будет указывать на адрес хранения целого числа i
:int i = 5;Если при этом задать
int *p;
p = &i;
*p = 10;Это изменит и значение
i
на 10
.Указатели могут быть объявлены для структур, как в следующем примере:
Coords x = new Coords();Затем можно использовать объявленный указатель
Coords *y = &x;
y
для доступа к открытому полю структуры x
(например, z
):(*y).zлибо через
->
:y -> zНебезопасный Код
Основная проблема с использованием указателей в C# в том, что CLR управляет процессом сбора мусора в фоновом режиме. Освобождая память, сборка мусора может изменить расположение объекта без предупреждения и испортить указатель на него. Это может как поставить под угрозу работу программы, так и повлиять на целостность других программ. Из-за этих проблем использование указателей ограничено кодом, который программист явно помечает как «небезопасный» (
unsafe
).Чтобы решить эту проблему, можно объявить указатель в выражении
fixed
. Это «фиксирует» расположение объекта по указателю, поэтому сборка мусора не ломает указатель. Оператор fixed
может использоваться только в контексте небезопасного кода. При этом типы значений, объявленные в небезопасном коде, автоматически фиксируются, их не нужно использовать в выражениях fixed
.Указатель может быть объявлен для массива:
int[] a = {4, 5};В этом случае
int *b = a;
b
указывает на ячейку памяти с первым элементом массива a
. Элементы также должны быть типа значения. Ниже показано, что можно проходить по значениям массива с помощью указателя:public static void Main() {Источник: https://codewithshadman.com/csharp-pointer/
int[] a = {4, 5};
changeVal(a);
Console.WriteLine(a[0]);
Console.WriteLine(a[1]);
}
public unsafe static void changeVal(int[] a) {
fixed (int *b = a) {
*b = 5;
*(b + 1) = 7;
}
}
День пятьсот одиннадцатый. #CSharp9
C# 9: Упрощённая Проверка Параметров на Null
Эта функция конкурировала с несколькими другими предложениями: атрибуты, флаги компилятора и т.п. Все они были отброшены в пользу узкоспециализированного предложения, которое уменьшает объем кода проверки параметра на
Оператор
1. Проверки на
2. Выполняется именно проверка на равенство
3. В конструкторе проверка произойдет после вызова конструктора базового класса. В Microsoft рассматривали возможность проверки параметров перед вызовом конструктора базового класса. Это всегда было разрешено в .NET и, возможно, это предпочтительнее. Тем не менее, синтаксис C# не позволяет этого, и было решено не генерировать код, который не может быть воссоздан без использования этой функции.
4. В итераторе проверка всегда выполняется при первоначальном вызове.
5. Ошибки компиляции возникнут в случаях:
- проверки параметра, который не может быть
- проверки параметра метода без реализации (например, абстрактного или частичного метода, делегата, метода интерфейса),
- проверки
6. Предупреждения компилятора возникнут в случаях:
- Проверки явно обнуляемого параметра
- Проверки необязательного параметра со значением
Предполагаются следующие сценарии для дженериков:
C# 9: Упрощённая Проверка Параметров на Null
Эта функция конкурировала с несколькими другими предложениями: атрибуты, флаги компилятора и т.п. Все они были отброшены в пользу узкоспециализированного предложения, которое уменьшает объем кода проверки параметра на
null
до одного символа.Оператор
!
может быть расположен после любого идентификатора в списке параметров, что заставит компилятор C# выдать стандартный код проверки на null для этого параметра:void M(string name!) {…}будет скомпилировано как:
void M(string name) {Правила довольно очевидны:
if (name is null)
throw new ArgumentNullException(nameof(name));
…
}
1. Проверки на
null
вводятся в начале функции перед любым другим кодом и выполняются в том же порядке, что и параметры в сигнатуре функции.2. Выполняется именно проверка на равенство
null
, игнорируя любые перегрузки оператора ==
.3. В конструкторе проверка произойдет после вызова конструктора базового класса. В Microsoft рассматривали возможность проверки параметров перед вызовом конструктора базового класса. Это всегда было разрешено в .NET и, возможно, это предпочтительнее. Тем не менее, синтаксис C# не позволяет этого, и было решено не генерировать код, который не может быть воссоздан без использования этой функции.
4. В итераторе проверка всегда выполняется при первоначальном вызове.
5. Ошибки компиляции возникнут в случаях:
- проверки параметра, который не может быть
null
(например, struct
, unmanaged
),- проверки параметра метода без реализации (например, абстрактного или частичного метода, делегата, метода интерфейса),
- проверки
out
параметра.6. Предупреждения компилятора возникнут в случаях:
- Проверки явно обнуляемого параметра
(string? x!)
. Предположительно это не приводит к ошибке, чтобы позволить подклассу быть более строгим, чем базовый класс.- Проверки необязательного параметра со значением
null
по умолчанию.Предполагаются следующие сценарии для дженериков:
void M<T>(T value!) { } // OKНедостаток этого подхода в том, что он не поддерживает проверку свойств, поскольку параметр
void M<T>(T value!) where T : struct { } // ошибка
void M<T>(T value!) where T : unmanaged { } // ошибка
void M<T>(T value!) where T : notnull { } // OK
void M<T>(T value!) where T : class { } // OK
void M<T>(T value!) where T : SomeStruct { } // ошибка
void M<T>(T value!) where T : SomeClass { } // OK
value
не задаётся явно, а только подразумевается. Пользователи предложили обходной путь, в котором оператор !
применяется к ключевому слову set
:public Foo Foo {get; set!;}Источник: https://www.infoq.com/news/2020/06/CSharp-9-Null/
public Bar Bar {
get { return bar; }
set! { bar = value; DoSomethingElse(); }
}
День пятьсот двенадцатый. #Оффтоп
5 Качеств Хорошего Программиста
Сегодня предложу вашему вниманию видео отклассового врага (шутка) джависта и блогера Сергея Немчинского «5 качеств хорошего программиста». Он избрал несколько необычный подход: качества, которые определяют хорошего программиста с точки зрения бизнеса, как хорошего работника, творца, «решателя проблем». Если спросить любого из вас, то вряд ли вы попадёте хотя бы в 2 качества, указанные в видео. Итак:
1. Интеллект
2. Страсть
3. Настойчивость
4. Любовь к новому и самообучению
5. Гибкость мышления
По-моему, интересная точка зрения. Строго говоря, многие из пунктов пересекаются между собой или связаны, а то и противоречат друг другу. Впрочем, не буду пересказывать, в видео Сергей объясняет каждое из качеств более подробно.
Что скажете? Обсудим в чате?
5 Качеств Хорошего Программиста
Сегодня предложу вашему вниманию видео от
1. Интеллект
2. Страсть
3. Настойчивость
4. Любовь к новому и самообучению
5. Гибкость мышления
По-моему, интересная точка зрения. Строго говоря, многие из пунктов пересекаются между собой или связаны, а то и противоречат друг другу. Впрочем, не буду пересказывать, в видео Сергей объясняет каждое из качеств более подробно.
Что скажете? Обсудим в чате?
YouTube
5 качеств хорошего программиста
Сегодня разберём какие пять качеств, я считаю, относятся к хорошему программисту.
Курсы для новичков:
JAVA - https://bit.ly/2Yo6yhm
JAVA Start - https://bit.ly/2zRjTFo
Инструментарий JAVA - https://bit.ly/2NiF2eG
Automation QA (Java) - https://bit.ly/313brhC…
Курсы для новичков:
JAVA - https://bit.ly/2Yo6yhm
JAVA Start - https://bit.ly/2zRjTFo
Инструментарий JAVA - https://bit.ly/2NiF2eG
Automation QA (Java) - https://bit.ly/313brhC…