Как стать автором
Обновить

Комментарии 57

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

А что мешает настроить отступы так, чтобы namespace не сдвигал их в тексте программы?

Раз это доработали, значит что-то мешает. Скорее всего, вручную сдвиги никто не трогает, т.к. в Visual Studio хороший режим автоформатирования. А настроить сдвиги для разных элементов вроде невозможно, да и будет странно выглядеть.

Странно назвать режим автоформатирования хорошим, если он не позволяет настраивать отступы в namespace и для этого потребовалось вносить доработки аж в сам синтаксис языка. Как по мне, очень своеобразная логика :-)

Кроме редактора, который не настраивается таким образом?


Наверное, мешает то, что пара фигурных скобок без отступа выглядит уродливо.

НЛО прилетело и опубликовало эту надпись здесь

вот эти record ктото сумел применять?

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

Да, перешли на них для DTO. Удобно клонировать и сравнивать

Да, с record код стал проще, но насчет "сравнивать" - есть нюансы:

private record Dto(string Name, List<int> Values);

public static void Main()
{
  var dto1 = new Dto("name", new List<int>() { 1 });
  var dto2 = new Dto("name", new List<int>() { 1 });

  Console.WriteLine(dto1 == dto2); // false !!!
}

Чуда нет… и зная .net понимаешь, почему так происходит (для ссылочных типов, если не переопределен метод Equals(), то сравнение делается по ReferenceEquals()). Но все же хотелось бы получить иной результат, раз уж везде пишут о том, как удобно сравнивать record-ы.

Да, для коллекций в рекордах надо использовать свои обёртки с переопределённым сравнением. Или неизменяемые типы из System.Collections.Immutable

А можете развернуть мысль касательно System.Collections.Immutable?
Я сейчас быстро проверил, и похоже, что обыкновенное сравнение неизменяемых коллекций даёт такой же результат как и сравнение обычных коллекций


var a = ImmutableList<int>.Empty.Add(1);
var b = ImmutableList<int>.Empty.Add(1);
Console.WriteLine(a.Equals(b)); // False

Тогда скорее "завернуть мысль". Перепутал с коллекциями из language-ext.

Тут будет обратный эффект, так как коллекция неизменяемая, то после добавления элемента у вас по сути будет новый экземпляр коллекции.

НЛО прилетело и опубликовало эту надпись здесь

Походу это тоже работает) По крайней мере, сейчас попробовал убрать "namespace MyApp;" в файле класса - всё собралось нормально с глобальным неймспейсом проекта.

НЛО прилетело и опубликовало эту надпись здесь
Такое и раньше работало, но так делать не стоит

Почему нет? Разве не давно была пропертя в msbuild/csproj для определения дефолтного неймспейса? С приходом нового упрощённого csproj эта пропертя теперь не включена в проект и имеет значение имени проекта по умолчанию.

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

Эта самая "пропертя" использовалась при сборке ресурсов, а также при создании новых файлов с кодом. Но на процесс компиляции она не влияла никогда.

Или автозадание namespace из структуры проекта.

А как же тогда папки с кодом делать?

Но при наследовании есть одна особенность: переопределенный вами метод ToString не будет унаследован потомками от родительской записи. Для того чтобы потомки записей наследовали метод ToString, стало доступно использование ключевого слова sealed, которое запрещает компилятору генерировать имплементацию метода ToString у дочерних записей.

Выглядит как баг, который оказалось настолько сложно исправить, что пришлось запилить костыль, работающий для некоторых случаев. А если я хочу использовать родительскую имплементацию ToString во всех наследниках кроме одного-двух? Тупик, метод запечатан, его уже не переопределить.

Интересный факт. Данное нововведение относится к интерполированию строк, то есть добавление константного символа не допускается:

Очень странная, ничем не обоснованная особенность. Недоделка, которую исправят в С# 11?

В запечатанном ToString вызовите свой виртуальный ToCustomString. Переопределяйте его по необходимости. Он то не будет автоматом переопределяться

Вообще-то особенность ещё как обоснованная: форматирование объектов, в общем случае, зависит от текущей культуры потока и не может быть выполнено во время компиляции, так что как ни крути — придётся вводить белый список того что может быть сделано компилятором. Сейчас в этот белый список вошли строки. Да, символы можно было включить тоже, но зачем?

В общем-то незачем, конечно (впрочем, и без интерполированнных строк в константах можно было жить), просто выглядит неконсистентно. Это как разрешить операцию сложения только для многозначных чисел, но не для однозначных

Мое личное мнение: пара полезных семантических вещей, которых раньше не хватало, и которые удобно реализовать было нельзя: это инициализация элеметов структур и конструктор стурктуры по умолчанию…

… и толстый слой молочного шоколада синтаксического сахара.
А «одновременное использование объявленных и инициализируемых переменных при деконструировании» в операторе switch еще не ввели?

По идее это как раз нужно для полноценного паттерн матчинга по составным объектам (кортежам и т.п.), когда в case-паттерне задается часть полей, а другая часть объявляется как новые переменные. Если заданные поля совпадают с соответствующими полями аргумента switch, то поля, объявленные как переменные, инициализируются соответствующими полями из аргумента switch.

Расширять работу с expression планируют? Например with в лямбдах?

а поподробнее пример-пожелание можно?

Хорошие нововведения и конкурсы интересные.

Да исключите наконец слово new из создания объекта. Точнее сделайте его факультативным.

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

Пример (абсолютно синтетический):

private MyClass MyClass(long x) => new MyClass((int)x+1);

var p = MyClass(1) ;

Сейчас вызывается метод, а если отказаться от new - будет вызываться конструктор, как более подходящая перегрузка.

Хотел написать, что для анонимных объектов это могло бы сработать, но там могут быть неприятные эффекты, когда блок кода с присвоением переменной из-за неправильно поставленной точки с запятой будет трактоваться как создание анонимного объекта без присваивания куда-то.

{ x = 1 };

{ x = 1; }

В Котлин пришлось object сделать ключевым словом, чтобы new убить. Хотя там конечно специфика JVM еще, например functionName ClassName - сразу видно где конструктор, где функция. Ну и сама среда немного другое разрешает.

Самое интересное в C#10 - абстрактные статические методы в интерфейсах, но они пока в preview, чтобы Микрософт смог собрать обратную связь и зарелизить их в C#11 с учётом пожеланий программистов. Так что пользуйтесь ими в своих любительских проектах и жалуйтесь.

А я правильно помню, что в .NET 6 опцию можно включить и фича появляется?

Смотрю на нововведения, как они читаются/выглядят, и сравниваю новинками C++. Плюсы делают реально инопланетяне.

Нововведения ниочем.

Последнее существенное - record все остальное это просто присыпка сахаром и побрызгивание дезодорантом.... Язык по сложности скатывается к C++ но конечно до этого еще далеко, хотя тенденцию видно.

Всегда можно попробовать F# :)

Это было бы прекрасно если бы этот язык продвигали в продакшен но к сожалению найти вакансию с C# гораздо легче чем с F# несмотря на то что после F# обратно уже не хочется. Я использую F# для своих внутренних утилит но последний раз когда я попытался исходники утилиты написанную на нем залить в репозиторий то выслушал много идиоматических выражений от кастомера что я "исказил и обфусцировал исходники С#".

На самом деле не так уж и больно с F# на C# возвращаться. С Котлин на Java больнее:)

Прошу прощения, что не совсем по теме. Посоветуйте, пожалуйста, актуальную литературу/курсы по C# (.NET). Желательно на русском, хотя бы для начала. Сейчас пока по сайту Метанит осваиваю.

Если Вы находитесь на начальном уровне, Вам подойдёт любая книга, где освещены все возможности языка, начиная с базовых. Обычно они очень толстые. Берите самое свежее издание, какое найдёте. С ростом опыта подход к обучению надо изменить, но пока так.

Советую еще посмотреть курсы на ulearn от УрФУ, по моему один из лучших курсов по C# для начинающих

Не читайте "любую", читайте эту. И http://ulearn.me.

Required properties не добавили, расходимся.

Можно небольшое описание того, что это, для чего и как должно работать? Заранее спасибо.

Это киллер фича, которая обязывает инициализировать указанные свойства в DTO.

Казалось бы есть конструктор для этого, но систаксис с инициализатором свойств намного удобнее. Это ещё один шаг в борьбе с NullReferreceException.

https://github.com/dotnet/csharplang/blob/main/proposals/required-members.md

https://github.com/dotnet/csharplang/issues/3630

И в догонку Simplified parameters null validation. Которое гарантирует null-безапасность и пишет бойлерплейт за вас.

// Before
void Insert(string s) {
  if (s is null)
    throw new ArgumentNullException(nameof(s));
  ...
}

// After
void Insert(string s!) {
  ...
}

https://github.com/dotnet/csharplang/issues/2145

В оригинальном репозитории богатый список киллер фич. Абсолютно без сарказма. Но из предложений в реальные обновления попадают единицы.

Добавляют потихоньку. Лучше медленно, но в верном направлении.

Мне казалось, что они ее в preview-режиме выпустят. Но могу ошибаться.

А зачем static нужны именно в интефейсах?
IMHO им место в ограничениях для класса, в where.

Интерфейс (точнее — ссылка на него) — это то, к чему можно привести (ссылку на) экземпляр типа, и вызвать его экземплярные методы как виртуальные (AKA через позднее связывание), т.е. — некая дополнительная виртуальная таблица, котоорая может присутвовать во многих классах. А статические методы экземпляров не требуют.

Тем более, что ограничения по наличию методов, реализованных в классе, в языке уже реально присутствуют (например — ограничения на то, что стоит после оператора await). Так что IMHO лучше бы их включить в синтаксис в явном виде (вроде, было когда-то такое предложение, что с ним сейчас — не в курсе) И ограничения на обязательность реализации статических методов войдут туда вполне органично.

Они рассматривали несколько вариантов, в итоге решили, что проще разрешить статику в интерфейсах, чем вводить дополнительные синтаксические сахарюшки. Т.е. если в generic'е хочется +, то нужно объявить:

Add<T>(T x, T y) where T: IAddable 

interface IAddable { static + }

В proposal'е это коротко написано. Если другие proposal'ы посмотреть, то че только не предлагали: начиная с тайпклассов, заканчивая трейтами. ИМХО, у C# прослеживается довольно выигрышная стратегия вводить хорошие частные решения для типовых задач. Когда Бреслав говорит, что "у нас async/await - это не ключевые слова, а функции, а ключевое слово у нас suspend" я не вполне уверен, что это преимущество Котлина, потому что чтобы использовать async/await без понимания внутренностей достаточно не использовать .Result и всегда предпочитать асинхронные версии методов и не оборачивать синхронные в Task.Run. С корутинами все несколько сложнее на мой вкус...

Они рассматривали несколько вариантов, в итоге решили

Ну, решать-то, конечно. Им, но вот «особенности», которые в общую схему языка не вписываются — типа await, выражение после которого должно просто иметь в описании некоторые буковки — один интерфейс и пару методов с фиксироваными названиями — я считаю, неплохо было бы таки вписать в общую схему языка.
Такая же фича есть и в LINQ query syntax — типа, что стоит во множественных from, должно реализовывать SelectMany с определенными параметрами — а там оно может быть что угодно. Но там хоть язык формально другой, отличающийся от основного массива C#
Тут проблема IMHO в том, что такие вот исключения из общих правил делают язык громоздким. Чем их больше — тем более громоздким он получается. А это — повышение требований к квалификации разработчика — при том, что индустрия сейчас и так страдает от завышенных требований, т.е. нехватки достаточно кавлифицированного персонала.
Но, конечно, пусть они делают там что хотят.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий