Здравствуйте, BlackEric, Вы писали:
BE>Список фич еще не объявлен же. BE>Вот их беклог: dotnet/csharplang. А скорость всегда пробуют улучшать.
Это же список изменений исключительно для C#?
А коллега выше приводил в основном предложения для Runtime.
Я понимаю, что они часто взаимосвязаны, но всё же это разные зоны и команды
Здравствуйте, _NN_, Вы писали:
_NN>Никто не хочет обсудить ? _NN>Похоже в .NET 10 нас ждут серьёзные улучшения производительности.
Появятся, обсудим. Обсуждать новости из будущего смысла нет. Несомненно оптимизации (не ломающие семантику) лишними не будут. В Яве это все давно сделано. Пора и в дотете сделать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Codealot, Вы писали:
C>Все сильнее становится ощущение, что чуваки пытаются переизобрести C++.
А можно пояснить откуда это ощущение и что вы вообще вкладываете в понятие "переизобрести C++"?
Я пробежался по ссылкам коллеги, но увидел только вполне себе логичные предложения по оптимизации JIT. Да, есть некая специфика .Net, но это и логично.
Здравствуйте, rudzuk, Вы писали:
R>Догнат и Перегнат!
Ну перегнать, наверное, пока нет.
Там в первой же ссылке они пишут, что тот же Interprocedural Analysis (IPA) — это фишка, в первую очередь, для AOT, но они хотят хотябы некоторые элементы сделать доступными JIT.
Т.е., в моем понимании, техники доступные классически компиляторам (производящим сразу исполнимый код — те же C++ компиляторы) для JIT будут слишком дорогими, а значит он заведомо в проигрышной ситуации.
Но с другой стороны, а все ли компиляторы (даже того же C++) реализуют весь набор оптимизаций?
Здравствуйте, rudzuk, Вы писали:
R>Есть списки оптимизаций в GCC и LLVM, насколько они соответствуют "всему набору"
То, что в конкретном компиляторе сделано максимум возможного, я не сомневаюсь.
Мой вопрос немного о другом. Фраза о переизобритении C++, как по мне, намекает, что благодаря неким особенностям языка все перечисленные оптимизации получаются сами собой, а значит во всех более-менее известных компиляторах они есть по определению
Иначе я в принципе не понимаю этой фразы — идут вполне рутинные работы по улучшению JIT-компилятора (даже не идут — пока обсуждаются), при чем тут C++?
Здравствуйте, Михаил Романов, Вы писали:
МР> R>Есть списки оптимизаций в GCC и LLVM, насколько они соответствуют "всему набору"
МР> То, что в конкретном компиляторе сделано максимум возможного, я не сомневаюсь.
LLVM, в данном случае, упоминается не столько, как конкретный компилятор, сколько, как распространенный бэкенд для различных компиятров других языков (кажется, это относится и к GCC). Например, МЦСТ делает поддержку архитектуры своих процов (Эльбрус) именно через LLVM, и таким образом любой компилятор использующий LLVM становится Эльбрус-совместимым (теоретически).
МР> Мой вопрос немного о другом. Фраза о переизобритении C++, как по мне, намекает, что благодаря неким особенностям языка все перечисленные оптимизации получаются сами собой, а значит во всех более-менее известных компиляторах они есть по определению
Я понял это по-другому. Из мильенького шарпа делают очередное чудище, впихивая все, что удается впихнуть (не конкретно данная новость, а общее движение вокруг). Возможно, я не прав, и автор подразумевал что-то другое.
МР>> Мой вопрос немного о другом. Фраза о переизобритении C++, как по мне, намекает, что благодаря неким особенностям языка все перечисленные оптимизации получаются сами собой, а значит во всех более-менее известных компиляторах они есть по определению
R>Я понял это по-другому. Из мильенького шарпа делают очередное чудище, впихивая все, что удается впихнуть (не конкретно данная новость, а общее движение вокруг). Возможно, я не прав, и автор подразумевал что-то другое.
Ну из шарпа хотят сделать многофункциональный — кроссплатформенный язык с поддержкой AOT, WebAssembly
C++ в том же AOT и WebAssembly играет промежуточную роль. Зачем изобретать новые сущности если уже есть инструменты в виде С++ который все и делает.
Проще скомпилировать в С++, а уже используя разные настройки скомпилировать все в AOT или WASM или еще куда
Программисту C# разбираться со всякими настройками С++ компилятора не нужно. Ему просто нужно выствить куда его код скомпилируется в итоге.
Как раз миленький шарп в итоге остается той же милотой!
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, rudzuk, Вы писали:
R>Я понял это по-другому. Из мильенького шарпа делают очередное чудище, впихивая все, что удается впихнуть (не конкретно данная новость, а общее движение вокруг). Возможно, я не прав, и автор подразумевал что-то другое.
Возможно.
Вот только автор исходного поста про изменения в C# вообще ни словом не упомянул. Он привел ссылки исключительно на предложения по улучшению JIT.
Здравствуйте, Serginio1, Вы писали:
S> Ну из шарпа хотят сделать многофункциональный — кроссплатформенный язык с поддержкой AOT, WebAssembly S> C++ в том же AOT и WebAssembly играет промежуточную роль. Зачем изобретать новые сущности если уже есть инструменты в виде С++ который все и делает. S> Проще скомпилировать в С++, а уже используя разные настройки скомпилировать все в AOT или WASM или еще куда
S> Программисту C# разбираться со всякими настройками С++ компилятора не нужно. Ему просто нужно выствить куда его код скомпилируется в итоге.
Дядя Сережа, ну ты базворд ходячий, блин...
S> Как раз миленький шарп в итоге остается той же милотой!
S>> Ну из шарпа хотят сделать многофункциональный — кроссплатформенный язык с поддержкой AOT, WebAssembly S>> C++ в том же AOT и WebAssembly играет промежуточную роль. Зачем изобретать новые сущности если уже есть инструменты в виде С++ который все и делает. S>> Проще скомпилировать в С++, а уже используя разные настройки скомпилировать все в AOT или WASM или еще куда
S>> Программисту C# разбираться со всякими настройками С++ компилятора не нужно. Ему просто нужно выствить куда его код скомпилируется в итоге.
R>Дядя Сережа, ну ты базворд ходячий, блин...
S>> Как раз миленький шарп в итоге остается той же милотой!
R>Милота-милота...
Здравствуйте, Михаил Романов, Вы писали:
МР>вполне себе логичные предложения по оптимизации JIT
Изначально, приоритет отдавался простоте кода и удобству, а не скорости. А сейчас они делают оптимизации в ущерб нужным вещам, которые никак не могут сделать уже почти десяток лет.
МР>>вполне себе логичные предложения по оптимизации JIT
C>Изначально, приоритет отдавался простоте кода и удобству, а не скорости. А сейчас они делают оптимизации в ущерб нужным вещам, которые никак не могут сделать уже почти десяток лет.
Изначально C# был сложнее Java за счет struct. В 2005 появились дженерики и главное это yield с энумераторами, плюс появились деревья выражений и самое главное из этого это Linq!
Так что приоритет отдавался не простоте, а удобству и функциональности.
Что касается скорости, то появление ref struct и ref Поля
это совместимость с нативным кодом и ускорение, без лишних копирований.
Что же касается Jit, то он никакого отношения к коду не имеет.
Его можно оптимизировать независимо от языка.
Здравствуйте, Serginio1, Вы писали:
S>В 2005 появились дженерики и главное это yield с энумераторами, плюс появились деревья выражений и самое главное из этого это Linq!
Писать проще, а не фич меньше.
S>Что же касается Jit, то он никакого отношения к коду не имеет. S>Его можно оптимизировать независимо от языка.
Только если у тебя бесконечные ресурсы. Которых на самом деле нет.
Здравствуйте, Codealot, Вы писали:
S>>Что же касается Jit, то он никакого отношения к коду не имеет. S>>Его можно оптимизировать независимо от языка.
C>Только если у тебя бесконечные ресурсы. Которых на самом деле нет.
Зачем бесконечные ресурсы. Производительность Jit по сравнению с С++ постоянно растет.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Codealot, Вы писали:
C>Только если у тебя бесконечные ресурсы. Которых на самом деле нет.
Вы предлагаете перекинуть ресурсы команды платформы на язык?
Здравствуйте, Codealot, Вы писали:
C>Здравствуйте, _NN_, Вы писали:
_NN>>Похоже в .NET 10 нас ждут серьёзные улучшения производительности.
C>Все сильнее становится ощущение, что чуваки пытаются переизобрести C++.
Конкретно решают проблему медленного старта приложений из-за JIT.
Посему работают надо Native AOT, чтобы программы запускались быстрее.
Это актуально для всяких утилит и для короткоживущих контейнеров.
Кстати, проблема настолько серьёзная, что некоторые команды в MS решили переписать с C# на Rust
А по поводу С++, это ведь гораздо приятнее писать на C# со всеми преимуществами платформы получая при этом быстродействие примерно нативного кода.
Здравствуйте, _NN_, Вы писали:
_NN>Это актуально для всяких утилит и для короткоживущих контейнеров. _NN>Кстати, проблема настолько серьёзная, что некоторые команды в MS решили переписать с C# на Rust
О! А можно поподробнее, что они там решили переписать и откуда это известно?
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Здравствуйте, _NN_, Вы писали:
_NN>>Это актуально для всяких утилит и для короткоживущих контейнеров. _NN>>Кстати, проблема настолько серьёзная, что некоторые команды в MS решили переписать с C# на Rust
Ф>О! А можно поподробнее, что они там решили переписать и откуда это известно?
Ну во первых об этом уже писали и не раз.
Во вторых об этом рассказывали непосредственно сами разработчики из Офиса.
Были у них утилиты на .NET Framework, которые перевели на .NET, но тут выяснилось, что он не является частью ситсемы и поэтому стартует гораздо медленней.
В последних .NET улучшили это дело с Ready2Run и следующим шагом работают над Native AOT, но когд это будет реально готово в производстве никто не знает.
Посему решили, что раз это утилиты и не что-то мегасложное можно и переписать на Rust, тем более когда такое движение вокруг языка.
Что там дальше с этим я не в курсах, не интересовался.
Здравствуйте, Codealot, Вы писали:
C>Здравствуйте, _NN_, Вы писали:
_NN>>Конкретно решают проблему медленного старта приложений из-за JIT.
C>А что конкретно тормозит и насколько?
Здравствуйте, Codealot, Вы писали:
C>А сейчас они делают оптимизации в ущерб нужным вещам, которые никак не могут сделать уже почти десяток лет.
A что в C# кроме DU так уж нужно?
.NET хорошая штука, но кажется они уже опоздали, для меня .NET это аналог джавы, вероятно чуть быстрее на каких-то коротких дистанциях, на длинных джава скорее всего будет выгоднее.
Go и Rust оттягивают на себя долю рынка.
При этом серверный рынок наверное проигран, т.е. выйти там в топ не удастся, GUI — что-то специфическое, наверное да, мобильный тоже нет. При том, что студию для линукса так никто и не сделал, а без решарпера студия — очень продвинутый блокнот.
Раньше винда vs линукс на десктопе имело большое значение, а сейчас куча все в вебе, гуи линухов подтянулся, а по браузеру шариться без разницы откуда, а остальных тулов не так уж и много. И такое ощущение, что в массе .NET сейчас особо никто и не выберет с нуля, при этом смузихлебы скажут что сложнаа, многа букаф, и это ваще не тренд.
Скорее возьмут и питон/го/раст, более того куча всевозможных либ, кешей, очередей и чего только нет — все написано. Т.е. сложный монолитный кеш (как Ignite) вряд ли кто-то будет писать на C#/
Тут сравнивают старт, рантайм, потребление памяти. Сейчас чистого кода в экосистеме компании работающего условно на шарпах ничтожна: базы Си/С++, очереди сообщений тоже + java, кубер на го, всякие кеши на java/Си/С++, какой смысо мне брать .NET если rest gateway на го, будет работать быстро и с мелким memory footprint, который будет сваливать сообщения в кафку, а дальше все относительно быстрое это го/раст, медленное питон.
Да Java/C# очень хороши для больших и сложных моделей, которые линкуются статически. Т.е. написать биллинг на питоне например или на го — идите в ж... потом сами собирайте все это г-но. Там где на джаве и шарпах можно решить вопрос атрибутами/аннотациями либами конфигами, на других языках придется писать и писать много.
Т.е. Java/C# для выстраивания "своей" сложной модели, но много ли тех, кто упирается в такие ограничения?
Текущие улучшения выглядят как "придержим старичков, чтобы не ушли", хотя язык прекрасен, может где-то уступает котлину в синтаксисе, но силен в управлении памятью, да и спецов еще найди по шарпам.
Здравствуйте, Codealot, Вы писали:
_NN>>выяснилось, что он не является частью ситсемы и поэтому стартует гораздо медленней. C>Что значит "не часть системы" и какое это имеет отношение к скорости?
Я пока не смотрел на ссылки, которые он дал — не знаю что там говорилось.
.NET Framework в Windows имеет Global Assembly Cache и Native Image Cache, у .NET такого нет (не было).
В первый кэш падают "глобальные" сборки, а во вторые — нативные образы, которые избавляют от необходимости в JIT-компиляции — они компилируются во время ngen install имя_сборки.
Вот всей этой подсистемы не было у .NET
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
_NN>>>выяснилось, что он не является частью ситсемы и поэтому стартует гораздо медленней. C>>Что значит "не часть системы" и какое это имеет отношение к скорости?
Ф>Я пока не смотрел на ссылки, которые он дал — не знаю что там говорилось. Ф>.NET Framework в Windows имеет Global Assembly Cache и Native Image Cache, у .NET такого нет (не было). Ф>В первый кэш падают "глобальные" сборки, а во вторые — нативные образы, которые избавляют от необходимости в JIT-компиляции — они компилируются во время ngen install имя_сборки.
Ф>Вот всей этой подсистемы не было у .NET
Так как .Net Core кроссплатформенный и нужно быть независимым от сборок на машине. Пошли другим путем.
Вы можете уменьшить время запуска и задержку приложения .NET, скомпилировав все сборки приложения в формат ReadyToRun (R2R). R2R является разновидностью компиляции AOT.
Бинарные файлы R2R повышают производительность при запуске, снижая объем работы, выполняемой на этом этапе компилятором JIT. Бинарные файлы содержат такой же машинный код, который создается компилятором JIT. Но бинарные файлы R2R имеют больший размер, так как содержат не только код на промежуточном языке (IL), который по-прежнему необходим для некоторых сценариев, но и версию того же кода на машинном языке. Функция R2R доступна только при публикации приложения, предназначенного для конкретной среды выполнения (RID), например для Windows x64 или Linux x64.
Здравствуйте, novitk, Вы писали:
N>Здравствуйте, Codealot, Вы писали:
C>>А сейчас они делают оптимизации в ущерб нужным вещам, которые никак не могут сделать уже почти десяток лет. N>A что в C# кроме DU так уж нужно?
Вынужден согласиться.
Для Линукс сегодня я есть Rider, но это не от MS.
От MS есть только VSCode и закрытый DevKit.
Начинать сегодня писать код сервисов на .NET это действительно будет странным выбором.
Экосистема Go ушла далеко вперёд.
Ну и конечно плюшки в виде простого развёртывания и быстрого старта никто не отменяет.
Здравствуйте, _NN_, Вы писали:
_NN>Начинать сегодня писать код сервисов на .NET это действительно будет странным выбором. _NN>Экосистема Go ушла далеко вперёд.
Смотря что писать: го — очень слабенький, невыразительный язык, почти ассемблер.
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Здравствуйте, _NN_, Вы писали:
_NN>>Начинать сегодня писать код сервисов на .NET это действительно будет странным выбором. _NN>>Экосистема Go ушла далеко вперёд.
Ф>Смотря что писать: го — очень слабенький, невыразительный язык, почти ассемблер.
Слабенький, да.
Но у него есть другие преимущества.
Здравствуйте, _NN_, Вы писали:
_NN>Вынужден согласиться. _NN>Для Линукс сегодня я есть Rider, но это не от MS. _NN>От MS есть только VSCode и закрытый DevKit.
Здравствуйте, novitk, Вы писали:
N>Здравствуйте, _NN_, Вы писали:
_NN>>Слабенький, да. _NN>>Но у него есть другие преимущества.
N>Раньше был АОТ, а сейчас где преимущества?
Я про преимущества Go.
Native .NET недостаточно зрел, чтобы можно пользоваться в продакшне.
У него достаточно ограничений.
Здравствуйте, _NN_, Вы писали:
N>>Раньше был АОТ, а сейчас где преимущества? _NN>Я про преимущества Go.
И я про них. Недостатков по сравнению с .NET там полный набор.
_NN>Native .NET недостаточно зрел, чтобы можно пользоваться в продакшне. _NN>У него достаточно ограничений.
Все эти ограничения есть и в GoLang. Он что умеет C++ CLI или runtime Linq code gen?
Здравствуйте, novitk, Вы писали:
N>Здравствуйте, _NN_, Вы писали:
N>>>Раньше был АОТ, а сейчас где преимущества? _NN>>Я про преимущества Go. N>И я про них. Недостатков по сравнению с .NET там полный набор.
_NN>>Native .NET недостаточно зрел, чтобы можно пользоваться в продакшне. _NN>>У него достаточно ограничений. N>Все эти ограничения есть и в GoLang. Он что умеет C++ CLI или runtime Linq code gen?
Так дело не в том, что он умеет или нет.
Дело в библиотеках, которые адаптированы под эти ограничения.
В .NET не все библиотеки могут так работать. Ну и количество работы не так уж мало.
А в Go изначально так нельзя и поэтому каждый решает проблему как может.
Бесспорно у нас будет .NET Native 20 , где всё будет работать, а Go уже сегодня работает десяток лет.
Здравствуйте, _NN_, Вы писали:
_NN>Дело в библиотеках, которые адаптированы под эти ограничения. _NN>В .NET не все библиотеки могут так работать. Ну и количество работы не так уж мало.
+1. Надо бы флажок в nuget добавить — AOP supported.
Today you may have an extension method that follows the pattern:
public static class Extensions
{
public static IEnumerable<int> WhereGreaterThan(this IEnumerable<int> source, int threshold)
=> source.Where(x => x > threshold);
}
The receiver is the parameter prefaced by the this keyword — source in this case. Property declarations do not have a similar location to declare the receiver. Thus, C# 14 introduces extension blocks. These are blocks with a scope that exposes the receiver to its contained members. If we switch the WhereGreaterThan extension method to the new syntax and add an IsEmpty property the extension block would be:
public static class Extensions
{
extension(IEnumerable<int> source)
{
public IEnumerable<int> WhereGreaterThan(int threshold)
=> source.Where(x => x > threshold);
public bool IsEmpty
=> !source.Any();
}
}
To use these members, you just call them:
var list = new List<int> { 1, 2, 3, 4, 5 };
var large = list.WhereGreaterThan(3);
if (large.IsEmpty)
{
Console.WriteLine("No large numbers");
}
else
{
Console.WriteLine("Found large numbers");
}
Generics are supported and the resolution rules are the same as for extension methods. For example, you could make WhereGreaterThan and IsEmpty generic:
extension<T>(IEnumerable<T> source)
where T : INumber<T>
{
public IEnumerable<T> WhereGreaterThan(T threshold)
=> source.Where(x => x > threshold);
public bool IsEmpty
=> !source.Any();
}
The constraint to INumber<T> allows the greater than operator to be used.
Static methods and properties don't have a receiver, so the extension block list the type without a parameter name:
extension<T>(List<T>)
{
public static List<T> Create()
=> [];
}
Extension blocks can seamlessly coexist with the extension methods you have today. There's no requirement to switch to the new syntax — both execute in exactly the same way. Just add extension blocks to the static classes that contain your existing extension methods.
The choice is entirely yours. If you prefer to leave your existing extension methods untouched, you absolutely can. But if you’d rather update your code for a consistent look and take advantage of the new syntax, that option is available too. And with tools like Visual Studio, converting to your preferred form has never been easier!
You'll see more extensions in upcoming previews, but we'd love to hear your feedback, so join the team and others in the community in the discussion Extensions.
Null-conditional assignment
Null-conditional assignment assigns a value to a property or field only if the containing instance exists. Imagine you have a code similar to:
public class Customer
{
public string Name { get; set; }
public int Age { get; set; }
}
public class UpdateCustomer
{
public static void UpdateAge(Customer? customer, int newAge)
{
if (customer is not null)
{
customer.Age = newAge;
}
}
}
You can simplify the UpdateAge method:
public static void UpdateAge(Customer? customer, int newAge)
{
customer?.Age = newAge;
}
If the customer is not null, Age will be updated. If customer is null, nothing will happen.
The IDE will help you by recommending this change via a lightbulb.
We'd love your feedback on this feature so join us and others in the community in the discussion on Null-conditional assignment.
и солнце б утром не вставало, когда бы не было меня
Table of Contents:
What’s New in .NET 10: Overview
Key Features and Essential Enhancements of .NET 10
How Can You Migrate to .NET 10 From Previous Versions?
End Note
Здравствуйте, Serginio1, Вы писали:
S>Thus, C# 14 introduces extension blocks.
Какая же дичь... Какой-то блок внутри класса, чтобы сэкономить на спичках.
Не знаю насколько реализуемо, но удобнее было бы что-то типа:
public static class Extensions extend IEnumerable<int>
{
public IEnumerable<int> WhereGreaterThan(int threshold)
=> this.Where(x => x > threshold);
public bool IsEmpty
=> !this.Any();
}
}
Их этот блок extension внутри класса как-то так себе выглядит и больше походит на высасывание синтаксического сахара, чтобы было.
S>Null-conditional assignment
Тоже как-то такое себе. По-моему это не такой уж частый случай, чтобы нужно было оптимизировать в плане написания.
А вот с поисками багов подозреваю, что будут проблемы.
Имелся опыт на проекте, где любили наркоманские свойства вида:
public int Value
{
get { CalcValue(); }
set {}
}
и:
public int Value
{
get { return _value; }
set
{
if (value < 0) return;
_value = value;
}
}
Меня это дико бесило и переделывал нормально, где дотягивались руки (периодически выплывали баги, т.к. разработчики по привычке не смотрели что у свойства пустой сеттер или он не всегда значения меняет, а потом удивлялись чего это они записывают в него одно значение, а фактически оказывается другое).
Тут конечно не такая наркомания, но сомневаюсь, что предлагаемая конструкция будет правильно читаться и не получится так, что ей просто NRE заглушится и ошибка тихо улетит куда-то дальше.
Статья какое-то рекламное говно, простите. Похоже просто сгенерирована чатГПТ.
Все перечисленные фичи взяты еще с .net8.
Из десятки ничего собственно нету.
Здравствуйте, BlackEric, Вы писали:
BE>Вот не плохая статья о нововведениях.
Без комментариев Как можно рекомендовать что-то, как "не плохое" даже не разобравшись?
Before:
var numbers = new List { 1, 2, 3, 4, 5 };
After (.NET 10 with C# 14):
var numbers = [1, 2, 3, 4, 5];
Приведённый выше для C#14 код не компилируется и не должен. Пока что collection expressions что назывется только target-typed, то есть должен быть известен тип, в который выражение необходимо преобразовать. Планов изменить это в C#14 пока нет.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Codealot, Вы писали:
C>Изначально, приоритет отдавался простоте кода и удобству, а не скорости.
Ну или просто не осилили по началу. А потом конкуренты стали на пятки наступать.
C>А сейчас они делают оптимизации в ущерб нужным вещам, которые никак не могут сделать уже почти десяток лет.
Это что же такого важного никак не могут реализовать?
Я вот только закрытие АлгТД могу вспомнить. И вряд ли это из-за того, что на оптимизации переключились.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, _NN_, Вы писали:
_NN>Ну во первых об этом уже писали и не раз.
Второй ссылки нет, а первая какие-то спекуляции.
_NN>Были у них утилиты на .NET Framework, которые перевели на .NET, но тут выяснилось, что он не является частью ситсемы и поэтому стартует гораздо медленней. _NN>В последних .NET улучшили это дело с Ready2Run и следующим шагом работают над Native AOT, но когд это будет реально готово в производстве никто не знает. _NN>Посему решили, что раз это утилиты и не что-то мегасложное можно и переписать на Rust, тем более когда такое движение вокруг языка. _NN>Что там дальше с этим я не в курсах, не интересовался.
Ну т.е. мелкую утилиту переписали, а ты уже далеко идущие выводы сделал?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, _FRED_, Вы писали:
_FR>Приведённый выше для C#14 код не компилируется и не должен. Пока что collection expressions что назывется только target-typed, то есть должен быть известен тип, в который выражение необходимо преобразовать. Планов изменить это в C#14 пока нет.
Спакуха. К C# 20 в МС на Расте напишут ИИ, который прочтёт исходники Немерла из 2005 года и реализует в C# 20 вывод типов из использования.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, _FRED_, Вы писали:
_FR>>Приведённый выше для C#14 код не компилируется и не должен. Пока что collection expressions что назывется только target-typed, то есть должен быть известен тип, в который выражение необходимо преобразовать. Планов изменить это в C#14 пока нет.
VD>Спакуха. К C# 20 в МС на Расте напишут ИИ, который прочтёт исходники Немерла из 2005 года и реализует в C# 20 вывод типов из использования.
Ну вот переменная может быть списком и массивом.
var numbers = [1, 2, 3, 4, 5];
затем я вызываю интеллисенс numbers.
Подсказка должна показывать свойства и методы списка и массива.
Кстати а как в TypeScript с объединениями
let id : number | string;
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Ну вот переменная может быть списком и массивом. S>
S>var numbers = [1, 2, 3, 4, 5];
S>
В Шарпе? Не может.
S> затем я вызываю интеллисенс numbers. S> Подсказка должна показывать свойства и методы списка и массива.
S>Кстати а как в TypeScript с объединениями
S>
S>let id : number | string;
S>
Ты тёплое с мягким путаешь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, 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<_, _>. Тут мы ограничили тип словарем, но позволили вывести параметры типов. В теории можно и так _<_, _>, но так Немерл не умеет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
S>> А в немерле какой тип выберет?
VD>В Nemerle такой синтаксис принципиально применим только ко встроенным в язык списками и проблемы с выводом типа самого списка не возникает.
VD>Но и если бы в Nemerle был такой же тип списка, проблем с выводом типов не произошло бы, так как Nemerle поддерживает вывод типов из использования. Переменная ведь куда-то дальше будет передана? Вот в этот момент будет вычислено пересечение типов и будет выведен минимально подходящий тип.
S>>>> Подсказка должна показывать свойства и методы списка и массива. S>> Так и не ответил какая подсказка нужна?
VD>Под подсказкой ты список комплита имеешь в виду?
VD>Это зависит от того подставил ли ты куда-то эту переменную или нет. Если ещё не подставил, то на переменной будет только ограничение "сверху", а это для дотнета IEnumerable<int>. VD>Если ты эту переменную коду-нибудь в функцию принимающую массив передашь, будет список членов массива, если в переменную (или что угодно накладывающую ограничение сверху) типа List<?>, будут члены List<int>.
Ну в итоге проще проставить тип, так как интеллисенс (комплит) нужен прежде всего.
А вот применение там где тип может быть определен это лишнее усложнение парсера.
Это же нужно не только для парсера, но и чтения кода.
и солнце б утром не вставало, когда бы не было меня
Ключевое слово 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 по-прежнему требует явно типизированного списка параметров.
и солнце б утром не вставало, когда бы не было меня