Today, we are glad to release .NET 7 Preview 2. The second preview of .NET 7 includes enhancements to RegEx source generators, progress moving NativeAOT from experimental status into the runtime, and a major set of improvements to the “dotnet new” CLI experience. The bits are available for you to grab right now and start experimenting with new features like:
- Build a specialized RegEx pattern matching engine using source generators at compile-time rather than slower methods at runtime.
- Take advantage of SDK improvements that provide an entirely new, streamlined tab completion experience to explore templates and parameters when running
dotnet new
. - Don’t trim your excitement, just your apps in preparation to try out NativeAOT with your own innovative solutions.
EF7 preview 2 was also released and is available on NuGet. You can also read what’s new in ASP.NET Core Preview 2.
You can download .NET 7 Preview 2, for Windows, macOS, and Linux.
- Installers and binaries
- Container images
- Linux packages
- Release notes
- Known issues
- GitHub issue tracker
We recommend you use the preview channel builds if you want to try .NET 7 with Visual Studio family products. Visual Studio for Mac support for .NET 7 previews isn’t available yet but is coming soon.
Preview 2
The following features are now available in the Preview 2 release.
Introducing the new Regex Source Generator
https://github.com/dotnet/runtime/issues/44676
Have you ever wished you had all of the great benefits that come from having a specialized Regex engine that is optimized for your particular pattern, without the overhead of building this engine at runtime?
We are excited to announce the new Regex Source Generator which was included in Preview 1. It brings all of the performance benefits from our compiled engine without the startup cost, and it has additional benefits, like providing a great debugging experience as well as being trimming-friendly. If your pattern is known at compile-time, then the new regex source generator is the way to go.
In order to start using it, you only need to turn the containing type into a partial
one, and declare a new partial method with the RegexGenerator
attribute that will return the optimized Regex
object, and that’s it! The source generator will fill the implementation of that method for you, and will get updated automatically as you make changes to your pattern or to the additional options that you pass in. Here is an example:
Before
public class Foo
{
public Regex regex = new Regex(@"abc|def", RegexOptions.IgnoreCase);
public bool Bar(string input)
{
bool isMatch = regex.IsMatch(input);
// ..
}
}
After
public partial class Foo // <-- Make the class a partial class
{
[RegexGenerator(@"abc|def", RegexOptions.IgnoreCase)] // <-- Add the RegexGenerator attribute and pass in your pattern and options
public static partial Regex MyRegex(); // <-- Declare the partial method, which will be implemented by the source generator
public bool Bar(string input)
{
bool isMatch = MyRegex().IsMatch(input); // <-- Use the generated engine by invoking the partial method.
// ..
}
}
And that’s it. Please try it out and let us know if you have any feedback.
CodeGen
Community PRs (Many thanks to JIT community contributors!!)
From @sandreenko
From @SingleAccretion
- Delete GT_DYN_BLK runtime#63026
- Address-expose locals under complex local addresses in block morphing runtime#63100
- Refactor optimizing morph for commutative operations runtime#63251
- Preserve OBJ/BLK on the RHS of ASG runtime#63268
- Handle embedded assignments in copy propagation runtime#63447
- Do not set GTF_NO_CSE for sources of block copies runtime#63462
- Exception sets: debug checker & fixes runtime#63539
- Stop using CLS_VAR for “boxed statics” runtime#63845
- Tune floating-point CSEs live across a call better runtime#63903
- Reverse ASG(CLS_VAR, …) runtime#63957
- Fix invalid threading of nodes in rationalization runtime#64012
- Add the exception set for ObjGetType runtime#64106
- Improve fgValueNumberBlockAssignment runtime#64110
- Commutative morph optimizations runtime#64122
- Fix unique VNs for ADDRs runtime#64230
- Copy propagation tweaking runtime#64378
- Introduce GenTreeDebugOperKind runtime#64498
- Add support for TYP_BYREF LCL_FLDs to VN runtime#64501
- Do not add NRE sets for non-null addresses runtime#64607
- Take into account zero-offset field sequences when propagating locals runtime#64701
- Another size estimate fix for movs runtime#64826
- Mark promoted SIMD locals used by HWIs as DNER runtime#64855
- Propagate exception sets for assignments runtime#64882
- Account for HWI stores in LIR side effects code runtime#65079
From @Wraith2
Dynamic PGO
Arm64
- Local heap optimizations on Arm64 runtime#64481
- Couple optimization to MultiRegStoreLoc runtime#64857
- Implement LoadPairVector64 and LoadPairVector128 runtime#64864
- ‘cmeq’ and ‘fcmeq’ Vector64.Zero/Vector128.Zero ARM64 containment optimizations runtime#62933
- Increase arm32/arm64 maximum instruction group size runtime#65153
- Prefer “mov reg, wzr” over “mov reg, #0” runtime#64740
- Biggen GC Gen0 for Apple M1 Fix LLC cache issue on Apple M1 runtime#64576
- Optimize full memory barriers around volatile reads/writes ARM64: Avoid LEA for volatile IND runtime#64354
- Optimize Math.Round(x, MidpointRounding.AwayFromZero/ToEven) runtime#64016
General Optimizations
- Security: Add JIT support for control-flow guard on x64 and arm64 runtime#63763
- Testing: Spmi replay asmdiffs mac os arm64 runtime#64119
Observability
static Meter s_meter = new Meter("MyLibrary.Queues", "1.0.0");
static UpDownCounter<int> s_queueSize = s_meter.CreateUpDownCounter<int>("Queue-Size");
static ObservableUpDownCounter<int> s_pullQueueSize = s_meter.CreateObservableUpDownCounter<int>("Queue-Size", () => s_pullQueueSize);
...
s_queueSize.Add(10);
s_queueSize.Add(-2);
Logging source generator improvements
- Logging source generator should gracefully fail when special parameters incorrectly get passed as template parameter runtime#64310
- Logging Source Generator fails to compile when in parameter modifier is present runtime#62644
- Logging Source Generator fails to compile using keyword parameters with @ prefixes runtime#60968
- Logging Source Generator fails ungracefully with overloaded methods runtime#61814
- Logging Source Generator fails to compile due to CS0246 and CS0265 errors if type for generic constraint is in a different namespace runtime#58550
SDK Improvements
[Epic] New CLI parser + tab completion #2191
For 7.0.100-preview2
, the dotnet new
command has been given a more consistent and intuitive interface for many of the subcommands that users already use. In addition, support for tab completion of template options and arguments has been massively updated, now giving rapid feedback on valid arguments and options as the user types.
Here’s the new help output as an example:
❯ dotnet new --help
Description:
Template Instantiation Commands for .NET CLI.
Usage:
dotnet new [<template-short-name> [<template-args>...]] [options]
dotnet new [command] [options]
Arguments:
<template-short-name> A short name of the template to create.
<template-args> Template specific options to use.
Options:
-?, -h, --help Show command line help.
Commands:
install <package> Installs a template package.
uninstall <package> Uninstalls a template package.
update Checks the currently installed template packages for update, and install the updates.
search <template-name> Searches for the templates on NuGet.org.
list <template-name> Lists templates containing the specified template name. If no name is specified, lists all templates.
New Command Names
Specifically, all of the commands in this help output no longer have the --
prefix that they do today. This is more in line with what users expect from subcommands in a CLI application. The old versions (--install
, etc) are still available to prevent breaking user scripts, but we hope to add obsoletion warnings to those commands in the future to encourage migration.
Tab Completion
The dotnet
CLI has supported tab completion for quite a while on popular shells like PowerShell, bash, zsh, and fish (for instructions on how to enable that, see How to enable TAB completion for the .NET CLI). It’s up to individual dotnet
commands to implement meaningful completions, however. For .NET 7, the new
command learned how to provide tab completion for
- Available template names (in
dotnet new <template-short-name>
)
❯ dotnet new angular
angular grpc razor viewstart worker -h
blazorserver mstest razorclasslib web wpf /?
blazorwasm mvc razorcomponent webapi wpfcustomcontrollib /h
classlib nugetconfig react webapp wpflib install
console nunit reactredux webconfig wpfusercontrollib list
editorconfig nunit-test sln winforms xunit search
gitignore page tool-manifest winformscontrollib --help uninstall
globaljson proto viewimports winformslib -? update
- Template options (the list of template options in the
web
template)
❯ dotnet new web --dry-run
--dry-run --language --output -lang
--exclude-launch-settings --name --type -n
--force --no-https -? -o
--framework --no-restore -f /?
--help --no-update-check -h /h
- Allowed values for those template options (choice values on an choice template argument)
❯ dotnet new blazorserver --auth Individual
Individual IndividualB2C MultiOrg None SingleOrg Windows
There are a few known gaps in completion – for example, --language
doesn’t suggest installed language values.
Future work
In future previews, we plan to continue filling gaps left by this transition, as well as make enabling completions either automatic or as simple as a single command that the user can execute. We hope that this will make improvements in tab completion across the entire dotnet
CLI more broadly used by the community!
What’s next
dotnet new
users – go enable tab completion and try it for your templating use! Template authors – try out tab completion for the options on your templates and make sure you’re delivering the experiences you want your users to have. Everyone – raise any issues you find on the dotnet/templating repo and help us make .NET 7 the best release for dotnet new
ever!
NativeAOT Update
We previously announced that we’re moving the NativeAOT project out of experimental status and into mainline development in .NET 7. Over the past few months, we’ve been heads down doing the coding to move NativeAOT out of the experimental dotnet/runtimelab repo and into the dotnet/runtime repo.
That work has now been completed, but we have yet to add first-class support in the dotnet SDK for publishing projects with NativeAOT. We hope to have that work done shortly, so you can try out NativeAOT with your apps. In the meantime, please try trimming your app and ensure there are no trim warnings. Trimming is a requirement of NativeAOT. If you own any libraries there are also instructions for preparing libraries for trimming.
Targeting .NET 7
To target .NET 7, you need to use a .NET 7 Target Framework Moniker (TFM) in your project file. For example:
<TargetFramework>net7.0</TargetFramework>
The full set of .NET 7 TFMs, including operating-specific ones follows.
net7.0
net7.0-android
net7.0-ios
net7.0-maccatalyst
net7.0-macos
net7.0-tvos
net7.0-windows
We expect that upgrading from .NET 6 to .NET 7 should be straightforward. Please report any breaking changes that you discover in the process of testing existing apps with .NET 7.
Support
.NET 7 is a Current release, meaning it will receive free support and patches for 18 months from the release date. It’s important to note that the quality of all releases is the same. The only difference is the length of support. For more about .NET support policies, see the .NET and .NET Core official support policy.
Breaking changes
You can find the most recent list of breaking changes in .NET 7 by reading the Breaking changes in .NET 7 document. It lists breaking changes by area and release with links to detailed explanations.
To see what breaking changes are proposed but still under review, follow the Proposed .NET Breaking Changes GitHub issue.
Roadmaps
Releases of .NET include products, libraries, runtime, and tooling, and represent a collaboration across multiple teams inside and outside Microsoft. You can learn more about these areas by reading the product roadmaps:
Closing
We appreciate and thank you for your all your support and contributions to .NET. Please give .NET 7 Preview 2 a try and tell us what you think!
https://dotnet.microsoft.com/en-us/download/dotnet/7.0
At this link it claims that the “Latest release date November 7, 2022” for SDK 7.0.100-preview.3
Fix this so that it has the proper release date please. Unless you are releasing software from the future. Then tell me about your time machine
What’s the comment moderation policy?
I’m asking because I believe my comment was deleted.
With NativeAOT requiring trimming, will trimming be supported for non-self-contained apps?
All NativeAOT apps are self-contained, so it’s not clear to me why that would be relevant.
AOT native compilation, finally it is happening! about time!!
I just tried the Regex source generator on a console project that is regex intensive. Execution time of a specific task went from ~11.3 seconds to ~2.2 seconds, which is really impressive. However, the fact only strings known at compile time is too restrictive : another part of the project use really long regexes that are constructed at runtime not because that aren't known at compile time but because building them with a fluent API...
I suppose you could use the new C# 6 Source Generator feature to run the fluent API code and emit methods with the
attribute 🙂
Execution time of a specific task went from ~11.3 seconds to ~2.2 seconds, which is really impressive.
How are you constructing the Regex taking 11.3 seconds? Did you specify RegexOptions.Compiled? There shouldn't be such a massive difference in throughput in .NET 7 between RegexOptions.Compiled and the source generator; other than one emitting IL and the other emitting C#, they share 99% of the same structure and optimizations. The primary benefits of the source generator...
@Stephen Toub, Just out of curiosity, if I write a source generator that emits code with the
attribute, will the RegexGenerator source generator still process the code that was emitted by my source generator? It seems like there’s potential for an infinite loop there.
Thank you! Great work 🙂
Still no ETA for java interop implementation in .NET? Maybe when release .NET 32.0? .NET promised this so many of us are waiting for that interop support.
The typical desktop app that I write these days uses AvaloniaUI and Serilog, I wonder how much are they compatible with Trimming and NativeAOT if I jump to .NET 7 Preview 2 ?
What happened with porting WCF to .Net 6 and possibly 7
Thanks all! Any chance to see GC regions in the next preview?