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

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День четыреста пятьдесят шестой. #CSharp9
Позиционное и Номинальное Создание Объектов. Начало
C# позволяет создавать объекты, используя позиционный или номинальный стиль.
- Позиционное создание предполагает использование конструктора для задания значений свойствам:
public class Person {
public string FirstName { get; }
public string LastName { get; }
public Person(string firstName, string lastName) {
FirstName = firstName;
LastName = lastName;
}
}
Person p = new Person("Charles", "Leclerc");
При наследовании для инициализации унаследованных свойств конструктор может вызывать конструктор базового класса.

- Номинальное создание предполагает использование инициализаторов:
Person p = new Person { FirstName = "Charles", LastName = "Leclerc" };

До сих пор проблема с инициализаторами была в том, что таким образом можно было задавать значения только доступным для записи свойствам. Инициализатор объекта - это просто синтаксический сахар. За кулисами он устанавливает значения свойствам после вызова конструктора. Таким способом невозможно создать неизменяемые типы. Поэтому часто приходится создавать конструкторы и использовать позиционный стиль.
См. также «Использование Неизменяемых Структур Данных в C#»

Номинальное Создание в C# 9
В C# 9 для создания неизменяемых типов предложен новый вид свойств только для инициализации с использованием ключевого слова init. Эти свойства могут быть установлены после выполнения конструктора, используя инициализатор объекта:
public class Person {
public string FirstName { get; init; }
public string LastName { get; init; }
}
Person p = new Person { FirstName = "Charles", LastName = "Leclerc" };

Свойства только для инициализации могут быть установлены в момент создания объекта, но становятся доступными только для чтения после завершения создания объекта. Когда требуется проверка при задании свойства, ключевое слово init может использоваться для определения блока проверки, так же как get и set. Кроме того, иногда может требоваться более сложная проверка, затрагивающая комбинацию нескольких свойств. В таком случае можно использовать новый валидатор с блоком кода, обозначенным ключевым словом init:
public class Person {
public string FirstName { get; init; }
public string LastName { get; init; }

init {
if (FirstName.Length + LastName.Length > 52)
throw new Exception("…");
}
}

Окончание следует…

Источник:
https://csharp.christiannagel.com/2020/04/21/c-9-positional-or-nominal-creation/
👍1
День четыреста пятьдесят седьмой. #CSharp9
Позиционное и Номинальное Создание Объектов. Окончание
Фабричный Метод и Выражение With
Для создания новых объектов из существующих предложено использовать конструкторы копий и фабричный метод или выражение With. В следующем фрагменте кода класс Person определяет конструктор копии, который возвращает новый объект Person. Метод With помечается как фабричный и вызывает конструктор копии. В классе Racer, производном от Person, определяется конструктор копии, который, в свою очередь, вызывает конструктор копии базового класса. Также переопределяется метод With базового класса для возврата объекта Racer.
public class Person {
public string FirstName { get; init; }
public string LastName { get; init; }

protected Person(Person p) =>
(FirstName, LastName) = (p.FirstName, p.LastName);
[Factory] public virtual Person With() =>
new Person(this);
}

public class Racer : Person {
public string RacingTeam { get; init; }

protected Racer(Racer r) : base(r) =>
RacingTeam = r.RacingTeam;
[Factory] public override Racer With() =>
new Racer(this);
}
Таким образом, можно создавать новые экземпляры со свойствами только для чтения. А поскольку метод With является фабричным, инициализатор объекта может быть использован для внесения некоторых изменений:
Person p1 = new Racer { FirstName = "Charles", LastName = "Leclerc", RacingTeam = "Ferrari" };
Person p2 = p1.With() { FirstName = "Arthur" };

Кроме того, предложено использовать выражение with вместо вызова фабричного метода:
Person p3 = p1 with { FirstName = "Arthur" };

Записи
Вместо определения конструктора копии и метода With также предлагается объявлять новый тип объектов – записи, используя ключевое слово record. В этом типе объектов будет автоматически создан конструктор копии, метод With, методы проверки на равенство и т.п.:
public record class Person {
public string FirstName { get; init; }
public string LastName { get; init; }
}
public record class Racer : Person {
public string RacingTeam { get; init; }
}
Person p1 = new Racer { FirstName = "Charles", LastName = "Leclerc", RacingTeam = "Ferrari" };
Person p2 = p1 with { FirstName = "Arthur" };

Источник: https://csharp.christiannagel.com/2020/04/21/c-9-positional-or-nominal-creation/
День пятьсот седьмой. #CSharp9
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/
День пятьсот девятый. #CSharp9
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/