Re[7]: .NET 10 улучшения
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.05.25 13:58
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> А в немерле какой тип выберет?


В Nemerle такой синтаксис принципиально применим только ко встроенным в язык списками и проблемы с выводом типа самого списка не возникает.

Но и если бы в Nemerle был такой же тип списка, проблем с выводом типов не произошло бы, так как Nemerle поддерживает вывод типов из использования. Переменная ведь куда-то дальше будет передана? Вот в этот момент будет вычислено пересечение типов и будет выведен минимально подходящий тип.

S>>> Подсказка должна показывать свойства и методы списка и массива.

S> Так и не ответил какая подсказка нужна?

Под подсказкой ты список комплита имеешь в виду?

Это зависит от того подставил ли ты куда-то эту переменную или нет. Если ещё не подставил, то на переменной будет только ограничение "сверху", а это для дотнета IEnumerable<int>.
Если ты эту переменную коду-нибудь в функцию принимающую массив передашь, будет список членов массива, если в переменную (или что угодно накладывающую ограничение сверху) типа List<?>, будут члены List<int>.


VD>>Ты тёплое с мягким путаешь.


S> Я спросил какая подсказка будет в TS.


Я ТайпСкриптом не занимаюсь и конкретики не знаю. Знаю только, что они создадут пересечение типов. Нечто вроде немерловых вариантов, но в автоматическом режиме. Могу только пофантазировать, что ничего кроме сравнения или разматчивания (в паттерн-матчинге) с такими переменными не должно быть доступно делать. Ну может какие-то методы из аналога их обжекта должны быть.

Но это вообще не о том. Для списков тип выводится совсем по другому. Тут не никаких пересечений типов. Список, с точки зрения дотнетного языка, это тип унаследованный от IEnumerable<T> с концертным подставленным параметром типов. Когда ты создаешь литерал абстрактного списка, он описывается как свободная переменная типа с наложенным ограничением свирху. Появляется эдакое уравнение типа. Тип L' >= IEnumerable<int>. int — потому, что тип элемента уже выведен. Все элементы типа int, а он структура, т.е. наследников не имеет. Вот если элементом будет некий класс, то будет еще сложнее. Будет две переменных типа с ограничениями с сверху. Тип элемента тоже будет переменной и у неё может быть ограничен тип переданными параметрами. Но так как в последствии в список можно "положить" и элементы другого типа, то окраничение будет частичным. В какой-то момент тип списка может быть опосредованно уточнён. Например, вызов:
class A {}
class B : A {}
class C : B {}
Foo(List<A> list);

var list = [new B()]; // тип с ограничением элемента E <= B (где переменная типа элемента). Тип списка L<E> >= IEnumerable<E >= B>
list.Add(new C()); // Проверить у него наличие Add() мы пока не можем. Но кода это удастся, тип списка будет по прежнему ограничен: IEnumerable<E >= B>, так как C > B. 
Foo(list); // Вот тут мы получаем уточнение и типа списка, и его элемента. Накладывается ограничение E >= List<E >= A>. В этот момент можно вычислить конкретный тип списка: List<B>.

Соответственно, если где-то типы не сойдутся, будет сообщение об ошибке.
Вот это и есть вывод типа из использования.

Еще можно задавать или уточнять тип частично. Например, x :> Dictionary<_, _>. Тут мы ограничили тип словарем, но позволили вывести параметры типов. В теории можно и так _<_, _>, но так Немерл не умеет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: .NET 10 улучшения
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.05.25 14:12
Оценка:
Здравствуйте, VladD2, Вы писали:


S>> А в немерле какой тип выберет?


VD>В Nemerle такой синтаксис принципиально применим только ко встроенным в язык списками и проблемы с выводом типа самого списка не возникает.


VD>Но и если бы в Nemerle был такой же тип списка, проблем с выводом типов не произошло бы, так как Nemerle поддерживает вывод типов из использования. Переменная ведь куда-то дальше будет передана? Вот в этот момент будет вычислено пересечение типов и будет выведен минимально подходящий тип.



S>>>> Подсказка должна показывать свойства и методы списка и массива.

S>> Так и не ответил какая подсказка нужна?

VD>Под подсказкой ты список комплита имеешь в виду?


VD>Это зависит от того подставил ли ты куда-то эту переменную или нет. Если ещё не подставил, то на переменной будет только ограничение "сверху", а это для дотнета IEnumerable<int>.

VD>Если ты эту переменную коду-нибудь в функцию принимающую массив передашь, будет список членов массива, если в переменную (или что угодно накладывающую ограничение сверху) типа List<?>, будут члены List<int>.

Ну в итоге проще проставить тип, так как интеллисенс (комплит) нужен прежде всего.
А вот применение там где тип может быть определен это лишнее усложнение парсера.
Это же нужно не только для парсера, но и чтения кода.
и солнце б утром не вставало, когда бы не было меня
Re: .NET 10 улучшения
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 17.07.25 13:37
Оценка: 82 (1)
Здравствуйте, _NN_, Вы писали:

https://devblogs.microsoft.com/dotnet/dotnet-10-preview-6/
https://learn.microsoft.com/ru-ru/dotnet/csharp/whats-new/csharp-14

Ключевое слово field
Токен field позволяет вам написать тело доступа к свойству, не объявляя явное поле для хранения данных. Маркер field заменяется на поле синтезированной резервной копии компилятора.

Например, ранее, если вы хотели убедиться, что свойство string не может быть установлено в null, вам нужно было объявить резервное поле и реализовать оба аксессора.



private string _msg;
public string Message
{
    get => _msg;
    set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}

Теперь вы можете упростить код следующим образом:


public string Message
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(value));
}

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

Возможны существенные изменения или путаница при чтении кода в типах, которые также содержат символ с именем field. Вы можете использовать @field или this.field, чтобы разрешить неоднозначность между field ключевым словом и идентификатором, или переименовать текущий field символ, чтобы обеспечить чёткое различие.

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

Контекстное ключевое слово field представлено в C# 13 в качестве предварительной функции.


Неявные преобразования диапазона
C# 14 предоставляет первоклассную поддержку для System.Span<T> и System.ReadOnlySpan<T> в языке. Эта поддержка включает новые неявные преобразования, позволяющие более естественное программирование с этими типами.

Span<T> и ReadOnlySpan<T> используются различными ключевыми способами в C# и среде выполнения. Их введение повышает производительность без риска безопасности. C# 14 распознает связь и поддерживает некоторые преобразования между ReadOnlySpan<T>, Span<T>и T[]. Типы span могут выступать в качестве получателей методов расширения, комбинироваться с другими преобразованиями и помогать в ситуациях вывода универсальных типов.

Список неявных преобразований диапазона можно найти в статье о встроенных типах в разделе справочника по языку. Дополнительные сведения см. в спецификации функции для типов диапазонов первого класса.

Несвязанные обобщенные типы и nameof
Начиная с C# 14 аргумент nameof может быть несвязанным универсальным типом. Например, nameof(List<>) принимает значение List. В более ранних версиях C# для возврата List<int> имени можно использовать только закрытые универсальные типы, например List.


Простые лямбда-параметры с модификаторами
Модификаторы параметров, например scoped, , ref, inoutили ref readonly лямбда-выражения, можно добавить без указания типа параметра:


delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);

Ранее добавление модификаторов было разрешено только в том случае, если объявления параметров включали типы параметров. В предыдущем объявлении требуется указывать типы для всех параметров.



TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);

Модификатор params по-прежнему требует явно типизированного списка параметров.

и солнце б утром не вставало, когда бы не было меня
Отредактировано 17.07.2025 13:38 Serginio1 . Предыдущая версия .
Re[2]: .NET 10 улучшения
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.08.25 21:02
Оценка: 76 (1) +1
Здравствуйте, Serginio1, Вы писали:

S>Ключевое слово field


Штука очень удобная. Особенно для реализации INotifyPropertyChanged:
public ReportError Error { get => field; private set => SetProperty(ref field, value); }


Но NET 10 тут никаким боком. Это фича C# 13 доступная даже с последними обновлениями NET 8 SDK.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.