{"id":46470,"date":"2023-07-11T10:05:00","date_gmt":"2023-07-11T17:05:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=46470"},"modified":"2024-12-13T14:18:42","modified_gmt":"2024-12-13T22:18:42","slug":"announcing-dotnet-8-preview-6","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-8-preview-6\/","title":{"rendered":"Announcing .NET 8 Preview 6"},"content":{"rendered":"<p>We&#8217;re delighted to let you know about the latest features and improvements coming with <a href=\"https:\/\/dotnet.microsoft.com\/next\">.NET 8 Preview 6<\/a>! This release is a continuation of the <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-8-preview-5\/\">Preview 5 release<\/a>, and we&#8217;re committed to bringing you more enhancements with each monthly release.<\/p>\n<p>Today we have an exciting release incorporated with plenty of library updates, a new WASM mode, more source generators, constant performance improvements, and NativeAOT support on iOS. We hope you enjoy these new features and improvements. Stay tuned for more updates as we continue our journey of making .NET better, together!<\/p>\n<p>You can <a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/8.0\">download .NET 8 Preview 6<\/a> for Linux, macOS, and Windows.<\/p>\n<ul>\n<li><a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/8.0\">Installers and binaries<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/dotnet-docker\/blob\/main\/documentation\/supported-tags.md\">Container images<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/core\/tree\/main\/release-notes\/8.0\">Release notes<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/core\/blob\/main\/release-notes\/8.0\/known-issues.md\">Known issues<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/core\/issues\">GitHub issue tracker<\/a><\/li>\n<\/ul>\n<p>There are several exciting posts you should check out as well:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/asp-net-core-updates-in-dotnet-8-preview-6\">ASP.NET Core<\/a> brings an improved startup debugging experience, Blazor enhancements, and metrics in the Preview 6 release. <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/new-csharp-12-preview-features\">C# 12<\/a> adds three new features for .NET 8 Preview 6: interceptors, inline arrays, and enhancements to the nameof expression.<\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-maui-in-dotnet-8-preview-6\">.NET MAUI<\/a> resolved 23 high-impact issues and introduces Native AOT for iOS in the Preview 6 release. <\/li>\n<li>Finally, today you can now enjoy .NET MAUI in .NET 8 using the <a href=\"https:\/\/aka.ms\/maui-devkit-blog\">new .NET MAUI extension for Visual Studio Code<\/a><\/li>\n<\/ul>\n<p>Stay current with what&#8217;s new and coming in <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/whats-new\/dotnet-8\">What&#8217;s New in .NET 8<\/a>. It will be kept updated throughout the release.<\/p>\n<p>Now, let&#8217;s take a look at some new .NET 8 features.<\/p>\n<p><a href=\"https:\/\/dotnet.microsoft.com\/next\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2023\/07\/dotnet-8-preview-6.png\" alt=\"Download .NET 8 Preview 6\" \/><\/a><\/p>\n<h2>System.Text.Json improvements<\/h2>\n<p>We made a number of improvements to the System.Text.Json source generator, primarily aimed at making Native AOT on par with the reflection-based serializer.<\/p>\n<ul>\n<li>Added caching support to the incremental generator, improving IDE performance in large projects. https:\/\/github.com\/dotnet\/runtime\/pull\/86121<\/li>\n<li>Improved formatting of source generated code, including fixes to a number of indentation issues https:\/\/github.com\/dotnet\/runtime\/pull\/86526, https:\/\/github.com\/dotnet\/runtime\/pull\/87557<\/li>\n<li>Added a number of new diagnostic warnings https:\/\/github.com\/dotnet\/runtime\/pull\/87980<\/li>\n<li>Fixed a number of bugs related to accessibility modifier resolution https:\/\/github.com\/dotnet\/runtime\/pull\/87136<\/li>\n<li>Ensures that types of ignored or inaccessible properties are not included by the generator https:\/\/github.com\/dotnet\/runtime\/pull\/87383<\/li>\n<li>Fix issues related to <code>JsonNumberHandling<\/code> support https:\/\/github.com\/dotnet\/runtime\/pull\/87484<\/li>\n<li>Fix support for recursive collection types https:\/\/github.com\/dotnet\/runtime\/pull\/87632<\/li>\n<li>Fix custom converter support for nullable structs https:\/\/github.com\/dotnet\/runtime\/pull\/84208<\/li>\n<li>Fix a number of bugs in the compile-time attribute parsing implementation https:\/\/github.com\/dotnet\/runtime\/pull\/87796<\/li>\n<li>Add support for nesting <code>JsonSerializerContext<\/code> declarations within arbitrary type kinds https:\/\/github.com\/dotnet\/runtime\/pull\/87829<\/li>\n<\/ul>\n<h3><code>JsonStringEnumConverter&lt;TEnum&gt;<\/code><\/h3>\n<p>This <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/87224\">new converter<\/a> complements the existing <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.text.json.serialization.jsonstringenumconverter?view=net-7.0\"><code>JsonStringEnumConverter<\/code><\/a> class, which is not supported in Native AOT.<\/p>\n<p>Users wishing to target Native AOT users should annotate their enum types with the following pattern.<\/p>\n<pre><code class=\"language-C#\">[JsonConverter(typeof(JsonStringEnumConverter&lt;MyEnum&gt;))]\r\npublic enum MyEnum { Value1, Value2, Value3 }\r\n\r\n[JsonSerializable(typeof(MyEnum))]\r\npublic partial class MyContext : JsonSerializerContext { }<\/code><\/pre>\n<h3><code>JsonConverter.Type<\/code><\/h3>\n<p>The <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/87382\">new property<\/a> allows users to look up the type of a non-generic <code>JsonConverter<\/code> instance:<\/p>\n<pre><code class=\"language-C#\">Dictionary&lt;Type, JsonConverter&gt; CreateDictionary(IEnumerable&lt;JsonConverter&gt; converters)\r\n    =&gt; converters.Where(converter =&gt; converter.Type != null).ToDictionary(converter =&gt; converter.Type!);<\/code><\/pre>\n<p>The property is nullable since it returns <code>null<\/code> for <code>JsonConverterFactory<\/code> instances and <code>typeof(T)<\/code> for <code>JsonConverter&lt;T&gt;<\/code> instances.<\/p>\n<h2>Stream-based ZipFile CreateFromDirectory and ExtractToDirectory method overloads<\/h2>\n<p>We <a href=\"https:\/\/github.com\/dotnet\/runtime\/issues\/1555\">added new overloads<\/a> of <code>ZipFile.CreateFromDirectory<\/code> that allow users to collect all the files included in a directory and zip them, then store the resulting zip file into the provided stream.<\/p>\n<p>Symmetrically, we added the <code>ZipFile.ExtractToDirectory<\/code> overloads that allow users to provide a stream containing a zipped file and extract its contents into the filesystem.<\/p>\n<p>These APIs can avoid having to use the disk as an intermediate step. This can be useful in scenarios where disk space is constrained, like, for example, in cloud-based environments:<\/p>\n<ul>\n<li><code>CreateFromDirectory<\/code> does not have to write the zipped result into disk.<\/li>\n<li><code>ExtractToDirectory<\/code> does not require the zipped file to be located in disk.<\/li>\n<\/ul>\n<h3><code>ZipFile.CreateFromDirectory<\/code> usage<\/h3>\n<pre><code class=\"language-cs\">Stream destinationStream = GetStreamFromSomewhere();\r\n\r\nZipFile.CreateFromDirectory(\r\n    sourceDirectoryName: \"\/home\/username\/sourcedirectory\/\",\r\n    destination: destinationStream,\r\n    compressionLevel: CompressionLevel.Optimal,\r\n    includeBaseDirectory: true,\r\n    entryNameEncoding: Encoding.UTF8);<\/code><\/pre>\n<h3><code>ZipFile.ExtractToDirectory<\/code> usage<\/h3>\n<pre><code class=\"language-cs\">Stream sourceStream = GetStreamFromSomewhere();\r\n\r\nZipFile.ExtractToDirectory(\r\n    source: sourceStream,\r\n    destinationDirectoryName: \"\/home\/username\/destinationdirectory\/\",\r\n    entryNameEncoding: Encoding.UTF8,\r\n    overwriteFiles: true);<\/code><\/pre>\n<h2><code>MetricCollector<\/code> Metrics API<\/h2>\n<p><a href=\"https:\/\/github.com\/dotnet\/extensions\/blob\/14917b87e8fc81f10d44ceea52d9b24e50e26550\/src\/Libraries\/Microsoft.Extensions.Telemetry.Testing\/Metering\/MetricCollector.cs#L22\">MetricCollector<\/a> is a new class that is designed to help test scenarios. It was previously called <code>InstrumentRecorder<\/code>. We&#8217;ve made significant improvements to this class and moved it to the <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.Extensions.Telemetry.Testing\/\">Microsoft.Extensions.Telemetry.Testing<\/a> package.<\/p>\n<p>The <code>MetricCollector<\/code> class can now record metric measurements along with timestamps. Additionally, the class offers the flexibility to use any desired time provider for accurate timestamp generation.<\/p>\n<p>The following example demonstrates how to use the feature.<\/p>\n<h3><code>MetricCollector<\/code> usage<\/h3>\n<pre><code class=\"language-C#\">const string CounterName = \"MyCounter\";\r\n\r\nvar now = DateTimeOffset.Now;\r\n\r\nvar timeProvider = new FakeTimeProvider(now);\r\nusing var meter = new Meter(Guid.NewGuid().ToString());\r\nvar counter = meter.CreateCounter&lt;long&gt;(CounterName);\r\nusing var collector = new MetricCollector&lt;long&gt;(counter, timeProvider);\r\n\r\nAssert.Empty(collector.GetMeasurementSnapshot());\r\nAssert.Null(collector.LastMeasurement);\r\n\r\ncounter. Add(3);\r\n\r\n\/\/ verify the update was recorded\r\nAssert.Equal(counter, collector.Instrument);\r\nAssert.NotNull(collector.LastMeasurement);\r\n\r\nAssert.Single(collector.GetMeasurementSnapshot());\r\nAssert.Same(collector.GetMeasurementSnapshot().Last(), collector.LastMeasurement);\r\nAssert.Equal(3, collector.LastMeasurement.Value);\r\nAssert.Empty(collector.LastMeasurement.Tags);\r\nAssert.Equal(now, collector.LastMeasurement.Timestamp);        <\/code><\/pre>\n<h2>Introducing the options validation source generator<\/h2>\n<p>To reduce startup overhead and improve validation feature set, we&#8217;ve <a href=\"https:\/\/github.com\/dotnet\/runtime\/issues\/85475\">introduced the source code generator<\/a> that implements the validation logic.<\/p>\n<h3>Options validation usage<\/h3>\n<pre><code class=\"language-C#\">\r\npublic class FirstModelNoNamespace\r\n{\r\n    [Required]\r\n    [MinLength(5)]\r\n    public string P1 { get; set; } = string. Empty;\r\n\r\n    [Microsoft.Extensions.Options.ValidateObjectMembers(typeof(SecondValidatorNoNamespace))]\r\n    public SecondModelNoNamespace? P2 { get; set; }\r\n\r\n    [Microsoft.Extensions.Options.ValidateObjectMembers]\r\n    public ThirdModelNoNamespace? P3 { get; set; }\r\n}\r\n\r\npublic class SecondModelNoNamespace\r\n{\r\n    [Required]\r\n    [MinLength(5)]\r\n    public string P4 { get; set; } = string. Empty;\r\n}\r\n\r\npublic class ThirdModelNoNamespace\r\n{\r\n    [Required]\r\n    [MinLength(5)]\r\n    public string P5 { get; set; } = string.Empty;\r\n}\r\n\r\n[OptionsValidator]\r\npublic partial class FirstValidatorNoNamespace : IValidateOptions&lt;FirstModelNoNamespace&gt;\r\n{\r\n}\r\n\r\n[OptionsValidator]\r\npublic partial class SecondValidatorNoNamespace : IValidateOptions&lt;SecondModelNoNamespace&gt;\r\n{\r\n}<\/code><\/pre>\n<p>If the app is using dependency injection, it can inject the validation using the following pattern.<\/p>\n<pre><code class=\"language-C#\">\r\nvar builder = WebApplication.CreateBuilder(args);\r\nbuilder.Services.AddControllersWithViews();\r\nbuilder.Services.Configure&lt;FirstModelNoNamespace&gt;(builder.Configuration.GetSection(...));\r\n\r\nbuilder.Services.AddSingleton&lt;IValidateOptions&lt;FirstModelNoNamespace&gt;, FirstValidatorNoNamespace&gt;();\r\nbuilder.Services.AddSingleton&lt;IValidateOptions&lt;SecondModelNoNamespace&gt;, SecondValidatorNoNamespace&gt;();<\/code><\/pre>\n<h2>Expanding LoggerMessageAttribute Constructor Overloads for Enhanced Functionality<\/h2>\n<p><a href=\"https:\/\/github.com\/dotnet\/runtime\/issues\/87254\">New <code>LoggerMessageAttribute<\/code> constructor overloads have been introduced<\/a>, offering greater flexibility in specifying the required parameters with reduced code. The new constructor overloads include options such as specifying only the LogLevel and message, only the LogLevel, or only the message.<\/p>\n<p>These enhancements make it easier for users to define LoggerMessageAttributes while minimizing unnecessary code.<\/p>\n<pre><code class=\"language-C#\">    public LoggerMessageAttribute(LogLevel level, string message);\r\n    public LoggerMessageAttribute(LogLevel level);\r\n    public LoggerMessageAttribute(string message);<\/code><\/pre>\n<h3><code>LoggerMessage<\/code> usage<\/h3>\n<p>The following example demonstrate an instantiation of <code>LoggerMessage<\/code> that previously wasn&#8217;t possible.<\/p>\n<pre><code class=\"language-C#\">        [LoggerMessage(Level = LogLevel.Warning, Message = \"{p1} should be valid\")]\r\n        public partial void LogWaraning(string p1);<\/code><\/pre>\n<p><em>Note<\/em>: In a later preview, for constructors that do not require an event Id, the system will automatically generate the event Id, eliminating the need for users to manually provide it.<\/p>\n<h2>Configuration binding source generator improvements<\/h2>\n<p>In <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-8-preview-3\/#introducing-the-configuration-binding-source-generator\">Preview 3<\/a>, we introduced a new source generator to provide AOT and trim-friendly <a href=\"https:\/\/learn.microsoft.com\/aspnet\/core\/fundamentals\/configuration\">configuration in ASP.NET Core<\/a>. The generator is an alternative to the pre-exising reflection-based implementation.  Since then, we&#8217;ve made several improvements based on community feedback and the generator is ready for folks to give it another go using Preview 6.<\/p>\n<p>An <a href=\"https:\/\/gist.github.com\/layomia\/d0da997f633310c2c6ee00fdca696371\">example app<\/a> that uses configuration binding and is published with AOT goes from having two (2) AOT analysis warnings during compilation to having none. The app would fail when executed but now it works.<\/p>\n<p>No source code changes are needed to use the generator. It&#8217;s enabled by default in Native AOT web apps. For other project types it is off by default, but you can control it by adding the following property to your project.<\/p>\n<pre><code class=\"language-csproj\">&lt;PropertyGroup&gt;\r\n    &lt;EnableConfigurationBindingGenerator&gt;true&lt;\/EnableConfigurationBindingGenerator&gt;\r\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<p>You can find known issues <a href=\"https:\/\/github.com\/dotnet\/runtime\/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-Extensions-Configuration+milestone%3A8.0.0+label%3Asource-generator+label%3Abug\">here<\/a>.<\/p>\n<h2>Source Generated COM Interop<\/h2>\n<p>We now have a new source generator that supports interoperating with COM interfaces using the <a href=\"https:\/\/learn.microsoft.com\/dotnet\/standard\/native-interop\/pinvoke-source-generation\">source generated interop support<\/a> that we started with <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.runtime.interopservices.libraryimportattribute?view=net-8.0\"><code>LibraryImportAttribute<\/code><\/a>. You can use the <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.runtime.interopservices.marshalling.generatedcominterfaceattribute?view=net-8.0\"><code>System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute<\/code><\/a> to mark an interface as a COM interface for the source generator. The source generator will then generate code to enable calling from C# code to unmanaged code, as well as code to enable calling from unmanaged code into C#. This source generator integrates with <code>LibraryImportAttribute<\/code>, and you can use types with the <code>GeneratedComInterfaceAttribute<\/code> as parameters and return types in <code>LibraryImportAttribute<\/code>-attributed methods.<\/p>\n<p>The COM source generator provides a straightforward IDE experience through analyzers and code fixers. This is similar to <code>LibraryImportAttribute<\/code>. Next to each interface that has the <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.runtime.interopservices.comimportattribute?view=net-8.0\"><code>System.Runtime.InteropServices.ComImportAttribute<\/code><\/a>, a lightbulb will offer an option to convert to source generated interop. This fix will change the interface to use the <code>GeneratedComInterfaceAttribute<\/code>. Next to every class that implements an interface with the <code>GeneratedComInterfaceAttribute<\/code>, a lightbulb will offer an option to add the <code>GeneratedComClassAttribute<\/code> to the type. Once your types are converted, you can move your <code>DllImport<\/code> methods to use <code>LibraryImportAttribute<\/code> with the existing code fixer there. With these two lightbulbs, it is easy to convert your existing COM interop code to use the new source generated interop. There are also more analyzers to help catch places where you may be mixing source-generated and runtime-based COM interop that may require additional work.<\/p>\n<p>As part of this project, we updated the <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.transactions?view=net-8.0\">System.Transactions library<\/a> to use the new source-generated interop! We used this experience to help refine the analyzers and code-fixers to provide a good migration experience.<\/p>\n<h3><code>GeneratedComInterface<\/code> usage<\/h3>\n<pre><code class=\"language-csharp\">using System.Runtime.InteropServices;\r\nusing System.Runtime.InteropServices.Marshalling;\r\n\r\n[GeneratedComInterface]\r\n[Guid(\"5401c312-ab23-4dd3-aa40-3cb4b3a4683e\")]\r\ninterface IComInterface\r\n{\r\n    void DoWork();\r\n}\r\n\r\ninternal class MyNativeLib\r\n{\r\n    [LibraryImport(nameof(MyNativeLib))]\r\n    public static partial void GetComInterface(out IComInterface comInterface);\r\n}<\/code><\/pre>\n<h3><code>GeneratedComClassAttribute<\/code><\/h3>\n<p>The source generator also supports the new <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.runtime.interopservices.marshalling.generatedcomclassattribute?view=net-8.0\"><code>System.Runtime.InteropServices.Marshalling.GeneratedComClassAttribute<\/code><\/a> to enable you to pass your types that implement interfaces with the <code>System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute<\/code>-attributed interfaces to unmanaged code. The source generator will generate the code necessary to expose a COM object that implements the interfaces and forwards calls to the managed implementation.<\/p>\n<h3><code>GeneratedComClassAttribute<\/code> usage<\/h3>\n<pre><code class=\"language-csharp\">using System.Runtime.InteropServices;\r\nusing System.Runtime.InteropServices.Marshalling;\r\n\r\nMyNativeLib.GetComInterface(out IComInterface comInterface);\r\ncomInterface.RegisterCallbacks(new MyCallbacks());\r\ncomInterface.DoWork();\r\n\r\n[GeneratedComInterface]\r\n[Guid(\"5401c312-ab23-4dd3-aa40-3cb4b3a4683e\")]\r\ninterface IComInterface\r\n{\r\n    void DoWork();\r\n    void RegisterCallbacks(ICallbacks callbacks);\r\n}\r\n\r\n[GeneratedComInterface]\r\n[Guid(\"88470b56-aabc-46af-bf97-8106a1aa3cf9\")]\r\ninterface ICallbacks\r\n{\r\n    void Callback();\r\n}\r\n\r\ninternal class MyNativeLib\r\n{\r\n    [LibraryImport(nameof(MyNativeLib))]\r\n    public static partial void GetComInterface(out IComInterface comInterface);\r\n}\r\n\r\n[GeneratedComClass]\r\ninternal class MyCallbacks : ICallbacks\r\n{\r\n    public void Callback()\r\n    {\r\n        Console.WriteLine(\"Callback called\");\r\n    }\r\n}<\/code><\/pre>\n<h3>Interacting with <code>LibraryImportAttribute<\/code><\/h3>\n<p>Methods on interfaces with the <code>GeneratedComInterfaceAttribute<\/code> support all the same types as <code>LibraryImportAttribute<\/code>, and <code>LibraryImportAttribute<\/code> gains support for <code>GeneratedComInterface<\/code>-attributed types and <code>GeneratedComClass<\/code>-attributed types in this release.<\/p>\n<p>If your C# code will only be use a <code>GeneratedComInterfaceAttribute<\/code>-attributed interface to either wrap a COM object from unmanaged code or wrap a managed object from C# to expose to unmanaged code, you can use the options in the <code>GeneratedComInterfaceAttribute.Options<\/code> property to customize which code will be generated. This option will enable you to not need to write marshallers for scenarios that you know will not be used.<\/p>\n<p>The source generator uses the new <a href=\"https:\/\/learn.microsoft.com\/dotnet\/api\/system.runtime.interopservices.marshalling.strategybasedcomwrappers?view=net-8.0\"><code>System.Runtime.InteropServices.Marshalling.StrategyBasedComWrappers<\/code><\/a> type to create and manage the COM object wrappers and the managed object wrappers. This new type handles providing the expected .NET user experience for COM interop, while providing customization points for advanced users. If your application has its own mechanism for defining types from COM or if you need to support scenarios that source-generated COM does not currently support, you can consider using the new <code>StrategyBasedComWrappers<\/code> type to add the missing features for your scenario and get the same .NET user experience for your COM types.<\/p>\n<h3>Limitations<\/h3>\n<p>Currently the COM source generator has the following limitations. We do not expect to address these limitations in .NET 8, but we may in a future version of .NET.<\/p>\n<ul>\n<li>No support for <code>IDispatch<\/code>-based interfaces.\n<ul>\n<li>Support for these interfaces may be manually implemented using a local definition of the <code>IDispatch<\/code> interface.<\/li>\n<\/ul>\n<\/li>\n<li>No support for <code>IInspectable<\/code>-based interfaces.\n<ul>\n<li>Use the <a href=\"https:\/\/github.com\/microsoft\/cswinrt\">CsWinRT tool<\/a> to generate the interop code for these interfaces.<\/li>\n<\/ul>\n<\/li>\n<li>No support for apartment affinity.\n<ul>\n<li>All COM objects are assumed to be free-threaded. Support for apartment affinity may be manually implemented using the <code>StrategyBasedComWrappers<\/code> type and custom strategy implementations.<\/li>\n<\/ul>\n<\/li>\n<li>No support for COM properties.\n<ul>\n<li>These may be manually implemented as methods on the interface.<\/li>\n<\/ul>\n<\/li>\n<li>No support for COM events.\n<ul>\n<li>These may be manually implemented using the underlying COM APIs.<\/li>\n<\/ul>\n<\/li>\n<li>No support for using the <code>new<\/code> keyword to activate a COM CoClass.\n<ul>\n<li>Use <code>LibraryImportAttribute<\/code> to P\/Invoke to the <code>CoCreateInstance<\/code> API to activate the CoClass.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>System.Security: SHA-3 Support<\/h2>\n<p><a href=\"https:\/\/github.com\/dotnet\/runtime\/issues\/20342\">Support for the SHA-3 hashing primitives<\/a> is now available on platforms that offer SHA-3. This is currently Linux with OpenSSL 1.1.1+ and Windows 11 build 25324+.<\/p>\n<p>APIs where SHA-2 is available now offer a SHA-3 compliment. This includes <code>SHA3_256<\/code>, <code>SHA3_384<\/code>, and <code>SHA3_512<\/code> for hashing; <code>HMACSHA3_256<\/code>, <code>HMACSHA3_384<\/code>, and <code>HMACSHA3_512<\/code> for HMAC; <code>HashAlgorithmName.SHA3_256<\/code>, <code>HashAlgorithmName.SHA3_384<\/code>, and <code>HashAlgorithmName.SHA3_512<\/code> for hashing where the algorithm is configurable; and <code>RSAEncryptionPadding.OaepSHA3_256<\/code>, <code>RSAEncryptionPadding.OaepSHA3_384<\/code>, and <code>RSAEncryptionPadding.OaepSHA3_512<\/code> for RSA OAEP encryption.<\/p>\n<p>Using the SHA-3 APIs is similar to SHA-2, with the addition of an <code>IsSupported<\/code> property to determine if the platform offers SHA-3.<\/p>\n<pre><code class=\"language-C#\">\/\/ Hashing example\r\n\/\/ Check if SHA-3-256 is supported on the current platform.\r\nif (SHA3_256.IsSupported)\r\n{\r\n    byte[] hash = SHA3_256.HashData(dataToHash);\r\n}\r\nelse\r\n{\r\n    \/\/ Determine application behavior if SHA-3 is not available.\r\n}\r\n\r\n\/\/ Signing Example\r\n\/\/ Check if SHA-3-256 is supported on the current platform.\r\nif (SHA3_256.IsSupported)\r\n{\r\n     using ECDsa ec = ECDsa.Create(ECCurve.NamedCuves.nistP256);\r\n     byte[] signature = ec.SignData(dataToBeSigned, HashAlgorithmName.SHA3_256);\r\n}\r\nelse\r\n{\r\n    \/\/ Determine application behavior if SHA-3 is not available.\r\n}<\/code><\/pre>\n<p>Additionally, SHA-3 includes two extendable-output functions (XOFs), SHAKE128 and SHAKE256. These are available as <code>Shake128<\/code> and <code>Shake256<\/code>.<\/p>\n<pre><code class=\"language-csharp\">if (Shake128.IsSupported)\r\n{\r\n    using Shake128 shake = new Shake128();\r\n    shake.AppendData(\"Hello .NET!\"u8);\r\n    byte[] digest = shake.GetHashAndReset(outputLength: 32);\r\n\r\n    \/\/ Also available as a one-shot:\r\n    digest = Shake128.HashData(\"Hello .NET!\"u8, outputLength: 32);\r\n}\r\nelse\r\n{\r\n    \/\/ Determine application behavior if SHAKE is not available.\r\n}<\/code><\/pre>\n<p>SHA-3 support is currently aimed at supporting cryptographic primitives. Higher level constructions and protocols are not expected to fully support SHA-3 initially. This includes, but is not limited to, X.509 certificates, <code>SignedXml<\/code>, and COSE. Support for SHA-3 may expand in the future depending on platform support and standards which adopt SHA-3.<\/p>\n<p>SHA-3 was standardized by NIST as FIPS 202 as an alternative to, not successor, to SHA-2. Developers and organizations should decide when or even if adopting SHA-3 is appropriate for them.<\/p>\n<h2>SDK: container publishing performance and compatibility<\/h2>\n<p>We&#8217;ve made a few changes to the <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-builtin-container-support-for-the-dotnet-sdk\/\">generated image<\/a> defaults for .NET 8 apps.<\/p>\n<ul>\n<li>Images now default to using the new <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/securing-containers-with-rootless\/\">rootless capability of .NET containers<\/a>, making your applications secure-by-default. You can change this at any time by setting your own <code>ContainerUser<\/code>, like <code>root<\/code>.<\/li>\n<li>Images are tagged as <code>latest<\/code> by default, the same as other container tools.<\/li>\n<\/ul>\n<p>We&#8217;ve improved the performance of container pushes to remote registries, the reliability of the push operation, and support for a larger range of registries. At the same time, <a href=\"https:\/\/github.com\/tmds\">Tom Deseyn<\/a> of Red Hat was busy improving our support for a range of prevalent container implementations.<\/p>\n<p>This version should see much improved performance for container pushes, especially to Azure registries. This is because of our improved support for pushing layers in one operation. In addition, for registries that don&#8217;t support atomic uploads, we&#8217;ve implemented a more reliable and re-try-able chunking upload mechanism.<\/p>\n<p>As a side effect of these changes, we also expanded our support matrix for registries. Harbor and Artifactory join the list of known-working registries, and Tom&#8217;s work enabled Quay.io and Podman pushes as well.<\/p>\n<h2><code>HybridGlobalization<\/code> mode on WASM<\/h2>\n<p>WASM apps can use a new globalization mode that brings lighter ICU bundle and leverages Web API instead. In Hybrid mode, globalization data is partially pulled from ICU bundle and partially from calls into JS. It serves all the <a href=\"https:\/\/github.com\/dotnet\/icu\/blob\/dotnet\/main\/icu-filters\/icudt_wasm.json\">locales supported by WASM<\/a>.<\/p>\n<h3>When to consider using <code>HybridGlobalization<\/code><\/h3>\n<p>This option is most suitable for applications that cannot work in <code>InvariantGlobalization<\/code> mode and use localization data from more than one ICU shard (EFIGS, CJK, no-CJK) &#8211; so currently using either:<\/p>\n<pre><code class=\"language-xml\">&lt;BlazorWebAssemblyLoadAllGlobalizationData&gt;true&lt;\/BlazorWebAssemblyLoadAllGlobalizationData&gt;<\/code><\/pre>\n<p>in Blazor WebAssembly or<\/p>\n<pre><code class=\"language-xml\">&lt;WasmIncludeFullIcuData&gt;true&lt;\/WasmIncludeFullIcuData&gt;<\/code><\/pre>\n<p>in WASM Browser.<\/p>\n<p>Apps that were loading no-CJK or CJK shard using the <a href=\"https:\/\/github.com\/dotnet\/runtime\/blob\/main\/docs\/design\/features\/globalization-icu-wasm.md\">custom ICU file loading method<\/a>:<\/p>\n<pre><code class=\"language-xml\">&lt;WasmIcuDataFileName&gt;icudt_no_CJK.dat&lt;\/WasmIcuDataFileName&gt;<\/code><\/pre>\n<p>might also be interested, because hybrid file is smaller than no-CJK shard by 26% and smaller than CJK by 15%.<\/p>\n<h3>How to use <code>HybridGlobalization<\/code><\/h3>\n<p>Set MsBuild property: <code>&lt;HybridGlobalization&gt;true&lt;\/HybridGlobalization&gt;<\/code>.  It will load <code>icudt_hybrid.dat<\/code> file that is 46% smaller than originally loaded <code>icudt.dat<\/code>.<\/p>\n<h3>Limitations<\/h3>\n<p>Due to limitations of Web API, not all Globalization APIs are supported in Hybrid mode. Some of the supported APIs changed their behavior. To make sure your application is will not be affected, read the section <a href=\"https:\/\/github.com\/dotnet\/runtime\/blob\/main\/docs\/design\/features\/globalization-hybrid-mode.md\">Behavioral differences for WASM<\/a>.<\/p>\n<p>APIs that obtain the result by calling into JS have worse performance than the non-hybrid version. These APIs are listed in the <a href=\"https:\/\/github.com\/dotnet\/runtime\/blob\/main\/docs\/design\/features\/globalization-hybrid-mode.md\">documentation<\/a>. The APIs that are not on the &#8220;Affected public APIs&#8221; lists perform the same as in non-hybrid mode.<\/p>\n<h2>Support for targeting iOS platforms with NativeAOT<\/h2>\n<p>We now have <a href=\"https:\/\/github.com\/dotnet\/runtime\/issues\/80905\">support for targeting iOS-like platforms<\/a> with Native AOT. This includes building and running <code>.NET iOS<\/code> and <code>.NET MAUI<\/code> applications with <code>NativeAOT<\/code> on: <code>ios<\/code>, <code>iossimulator<\/code>, <code>maccatalyst<\/code>, <code>tvos<\/code> or <code>tvossimulator<\/code> systems. The motivation of this work is to enable users to explore the possibility of achieving better performance and size savings when targeting such platforms with <code>NativeAOT<\/code>.<\/p>\n<p>This is available as an opt-in feature intended for app deployment, while <code>Mono<\/code> is still used as the default runtime choice for app development and deployment.\nThis milestone has been reached with a great collaboration between our community members: <a href=\"https:\/\/github.com\/filipnavara\">@filipnavara<\/a> <a href=\"https:\/\/github.com\/AustinWise\">@AustinWise<\/a> and <a href=\"https:\/\/github.com\/am11\">@am11<\/a> who contributed with their work, and joint effort of <code>NativeAOT<\/code>, <code>Mono<\/code> and <code>Xamarin<\/code> teams.<\/p>\n<h3>Current state<\/h3>\n<p>The current state has been tested with:<\/p>\n<ul>\n<li><code>.NET iOS app<\/code> (<code>dotnet new ios<\/code>)<\/li>\n<li><code>.NET MAUI iOS app<\/code> (<code>dotnet new maui<\/code>)<\/li>\n<\/ul>\n<p>These sample applications show the following preliminary results compared to <code>Mono<\/code>:<\/p>\n<table>\n<thead>\n<tr>\n<th>.NET iOS app<\/th>\n<th>Mono-p6<\/th>\n<th>NativeAOT-p6<\/th>\n<th>diff (%)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Size on disk (Mb)<\/td>\n<td>11,61<\/td>\n<td>6,99<\/td>\n<td>-40%<\/td>\n<\/tr>\n<tr>\n<td>.ipa (Mb)<\/td>\n<td>4,37<\/td>\n<td>2,69<\/td>\n<td>-39%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<thead>\n<tr>\n<th>.NET MAUI iOS app<\/th>\n<th>Mono-p6<\/th>\n<th>NativeAOT-p6<\/th>\n<th>diff (%)<\/th>\n<th>NativeAOT-fix<\/th>\n<th>diff (%)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Size on disk (Mb)<\/td>\n<td>40,24<\/td>\n<td>50,13<\/td>\n<td>25%<\/td>\n<td>27,58<\/td>\n<td>-31,46%<\/td>\n<\/tr>\n<tr>\n<td>.ipa (Mb)<\/td>\n<td>14,68<\/td>\n<td>16,59<\/td>\n<td>13%<\/td>\n<td>10,23<\/td>\n<td>-30,32%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The <code>.NET 8 Preview 6<\/code> results (marked as <code>*-p6<\/code>) show that the <code>.NET iOS app<\/code> has significant improvements compared to <code>Mono<\/code> where the compressed app bundle (.ipa) is up to <code>~39%<\/code> smaller showing great potential, while the <code>.NET MAUI iOS app<\/code> shows worse results producing <code>~13%<\/code> larger output. However, we have identified the root cause of the size regression with the <code>.NET MAUI<\/code> app and we are currently working on the following list of issues to address the size regression:<\/p>\n<ol>\n<li>https:\/\/github.com\/xamarin\/xamarin-macios\/pull\/18532<\/li>\n<li>https:\/\/github.com\/xamarin\/xamarin-macios\/issues\/18479<\/li>\n<li>https:\/\/github.com\/dotnet\/runtime\/issues\/87924<\/li>\n<li>https:\/\/github.com\/dotnet\/runtime\/issues\/86649<\/li>\n<\/ol>\n<p>By fixing the identified issues 1-3) we have estimated that <code>NativeAOT<\/code> can reach great results with the <code>.NET MAUI<\/code> app, which is shown in the column <code>NativeAOT-fix<\/code>, where the size of the application bundle is <code>~30%<\/code> smaller compared to <code>Mono<\/code>. Fixing the issue 4) would potentially improve the performance even further, but at this stage we cannot estimate the exact numbers. More information about <code>.NET MAUI<\/code> performance with <code>NativeAOT<\/code> is being tracked in: https:\/\/github.com\/dotnet\/runtime\/issues\/80907<\/p>\n<p>We would like to point out that conclusions regarding <code>NativeAOT<\/code> performance on iOS-like platforms should not be drawn out from the presented numbers in the table nor from the <code>.NET 8 Preview 6<\/code> release in general. Especially since this is still work-in-progress and only the first step towards making the feature ready for <code>.NET 9<\/code> official release. Therefore, we are actively working on improvements and identifying all the work that will try to bring full <code>NativeAOT<\/code> experience to our customers towards achieving great performance and size savings, which is being tracked in the following list of issues (and their subtasks):<\/p>\n<ul>\n<li>https:\/\/github.com\/dotnet\/runtime\/issues\/80905 tracks: Overall progress<\/li>\n<li>https:\/\/github.com\/xamarin\/xamarin-macios\/issues\/17339 tracks: <code>Xamarin<\/code> integration improvements<\/li>\n<li>https:\/\/github.com\/dotnet\/runtime\/issues\/86649 tracks: Trimming and extension compatibility improvements=<\/li>\n<\/ul>\n<h3>How to build and run a .NET MAUI application with NativeAOT on an iOS device with .NET CLI<\/h3>\n<h4>Installation<\/h4>\n<pre><code class=\"language-bash\">dotnet workload install maui<\/code><\/pre>\n<h4>Creating a sample application<\/h4>\n<pre><code class=\"language-bash\">dotnet new maui -n HelloMaui<\/code><\/pre>\n<h4>Choosing NativeAOT over Mono<\/h4>\n<p>The MSBuild properties <code>PublishAot=true<\/code> and <code>PublishAotUsingRuntimePack=true<\/code> (temporary, see below) enable <code>NativeAOT<\/code> deployments.<\/p>\n<p>These two properties are the only notable difference compared to when deploying with <code>Mono<\/code>.\nYou need to add them in a <code>PropertyGroup<\/code> of the project file of your application:<\/p>\n<pre><code class=\"language-xml\">&lt;PropertyGroup&gt;\r\n    &lt;PublishAot&gt;true&lt;\/PublishAot&gt;\r\n    &lt;PublishAotUsingRuntimePack&gt;true&lt;\/PublishAotUsingRuntimePack&gt;\r\n&lt;\/PropertyGroup&gt;<\/code><\/pre>\n<p>Which means that every time the app is deployed via <code>dotnet publish<\/code> it will be deployed by using <code>NativeAOT<\/code>.<\/p>\n<h4>Running your application<\/h4>\n<pre><code class=\"language-bash\">dotnet publish -f net8.0-ios -c Release -r ios-arm64  \/t:Run<\/code><\/pre>\n<h3>iOS and NativeAOT compatibility<\/h3>\n<p>Not all features in iOS are compatible with NativeAOT. Similarly, not all libraries commonly used in iOS are compatible with NativeAOT. .NET 8 represents the start of work to enable NativeAOT for iOS, your feedback will help guide our efforts during .NET 8 previews and beyond, to ensure we focus on the places where the benefits of NativeAOT can have the largest impact.<\/p>\n<p>The following list includes some limitations when targeting iOS-like platforms that have been encountered so far (and thus might not be the final list):<\/p>\n<ul>\n<li>Installation and app deployment by using Visual Studio have not been tested yet<\/li>\n<li>Using <code>NativeAOT<\/code> is only enabled during app deployment &#8211; <code>dotnet publish<\/code><\/li>\n<li><code>Linq.Expressions<\/code> library functionality is not fully supported yet<\/li>\n<li>The <code>PublishAotUsingRuntimePack=true<\/code> MSBuild property is a temporary workaround required for targeting iOS-like platforms with NativeAOT\n<ul>\n<li>This requirement will become obsolete by fixing: https:\/\/github.com\/dotnet\/runtime\/issues\/87060 <\/li>\n<\/ul>\n<\/li>\n<li>Managed code debugging is only supported with <code>Mono<\/code><\/li>\n<\/ul>\n<p>NOTE: The previous list is an extension to the limitations applicable for all platforms with <code>NativeAOT<\/code>: https:\/\/github.com\/dotnet\/runtime\/blob\/main\/src\/coreclr\/nativeaot\/docs\/limitations.md<\/p>\n<h2>CodeGen<\/h2>\n<h3>Community PRs (Many thanks to JIT community contributors!)<\/h3>\n<ul>\n<li>\n<p>@huoyaoyuan made use of ECMA-335 III.4.6 to optimize type checks involving <code>Nullable&lt;T&gt;<\/code>, <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/87241\">PR#87241<\/a>. @huoyaoyuan also made a fix for parameter ordering and value in <code>gtNewColonNode<\/code> in <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/87366\">PR#87366<\/a>. <\/p>\n<\/li>\n<li>\n<p>@jasper-d optimized new <code>Vector3 { X = val1, Y = val2, Z = val3 }<\/code> pattern to emit the same codegen as  <code>Vector3 { val1,val2, val3}<\/code> by folding <code>cost WithElement<\/code> to <code>CNS_VEC<\/code>, <a href=\"https:\/\/github.com\/dotnet\/runtime\/issues\/84543\">PR#84543<\/a>. <\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"language-c#\">Vector3 Foo1() =&gt; new Vector3 { X = 1, Y = 2, Z = 3 }; \r\nVector3 Foo2() =&gt; new Vector3(1, 2, 3); <\/code><\/pre>\n<ul>\n<li>\n<p>@pedrobsaila fused numeric <code>&lt;<\/code> and <code>==<\/code> comparisons to <code>&lt;=<\/code> and <code>&gt;<\/code> and <code>==<\/code> to <code>&gt;=<\/code> and reduced the number of instructions in <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/78786\">#PR78786<\/a>. <\/p>\n<\/li>\n<li>\n<p>@SingleAccretion has been working on internal JIT cleanup to greatly simplify the Internal Representation (IR). He removed <code>GT_ASG<\/code> IR that we had for many years, and it shows about 1 ~ 1.5% of throughput improvements, <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/85871\">PR#85871<\/a>. <\/p>\n<p><a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/85871\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2023\/07\/windows-x64-codegen.png\" alt=\"Windows x64 Codegen improvement\" \/><\/a><\/p>\n<\/li>\n<\/ul>\n<h3>AVX-512<\/h3>\n<p>Since we enabled Vector512 and AVX512 support in Preview 4, our community members continued to add new features. <\/p>\n<ul>\n<li>\n<p>@DeepakRajendrakumaran accelerated Vector256\/512.Shuffle() using AVX512 VBMI that improves performance by reducing data movement from memory to registers and rearranging data in the two memory addresses, <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/87083\">PR#87083<\/a>.  <\/p>\n<\/li>\n<li>\n<p>@Ruihan-Yin enabled EVEX feature that embeds broadcast and optimized Vector256.Add() when vector base type is <code>TYP_FLOAT<\/code>, <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/84821\">PR#84821<\/a>. <\/p>\n<\/li>\n<\/ul>\n<h3>Arm64<\/h3>\n<ul>\n<li>\n<p>@SwapnilGaikwad used Conditional Invert (<code>cinv<\/code>) and Conditional Negate (<code>cneg<\/code>) instead of Conditional Select(<code>csel<\/code>) that reduced code size and speed on Arm64 platform, <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/84926\">PR#84926<\/a>. <\/p>\n<p><a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/84926\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2023\/07\/arm64-codegen.png\" alt=\"Arm64 Codegen improvement\" \/><\/a><\/p>\n<\/li>\n<li>\n<p>@SwapnilGaikwad also combined two vector table lookups into one on Arm64 that shows 10-50% of speed-up on microbenchmarks such as <code>FormatterInt32<\/code>, <a href=\"https:\/\/github.com\/dotnet\/runtime\/pull\/87126\">PR#87126<\/a>. <\/p>\n<\/li>\n<li>\n<p>We changed register allocation to iterate over the registers of interest instead of over all the registers, which improved the JIT\u2019s own throughput for various scenarios by up to 5% on Arm64 and around 2% on x64.<\/p>\n<\/li>\n<\/ul>\n<h2>Community spotlight (<a href=\"https:\/\/github.com\/Wraith2\">Wraith2<\/a>)<\/h2>\n<blockquote>\n<p>I&#8217;m a career developer working in a mix of technologies from vb6 to netcore with most things in between. I maintain extend and assist in developing new products. I got started working with .net core using System.IO.Pipelines to efficiently parse a text based custom protocol that was causing performance concerns at work. I was very pleased with results but as soon as I started adding database access to the project suddenly there was a lot going on in performance profiles that didn&#8217;t seem to be needed. Since the runtime was open source I realized that I could improve what I found.<\/p>\n<p>I started contributing performance enhancements to the System.Data.SqlClient driver in the dotnet\/runtime repository and then once SqlClient was moved out of the runtime into a new project Microsoft.Data.SqlClient I continued to contribute there working with the team to improve the performance and stability of the driver. I&#8217;ve continued to take an interest in the runtime by reviewing code and occasionally adding new features like some new BMI instructions support in the JIT. Working on new and evolving codebase has allowed me to learn a lot about .net runtime and libraries by interacting with enthusiastic and knowledgeable contributors from all over the world.<\/p>\n<\/blockquote>\n<p>Do you know anybody who is contributing to .NET that we should feature in future posts? Nominate them at <a href=\"https:\/\/aka.ms\/net8contributor\">https:\/\/aka.ms\/net8contributor<\/a>.<\/p>\n<h2>Summary<\/h2>\n<p>.NET 8 Preview 6 contains exciting new features and improvements that would not be possible without the hard work and dedication of a diverse team of engineers at Microsoft and a passionate open-source community. We want to extend our <a href=\"https:\/\/dotnet.microsoft.com\/thanks\">sincere thanks to everyone who has contributed to .NET 8 so far<\/a>, whether it was through code contributions, bug reports, or providing feedback.<\/p>\n<p>Your contributions have been instrumental in the making of the .NET 8 Previews, and we look forward to continuing to work together to build a brighter future for .NET and the entire technology community.<\/p>\n<p>Curious about what is coming? <a href=\"https:\/\/dotnet.microsoft.com\/next\">Go see for yourself what&#8217;s next in .NET!<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re thrilled to announce .NET 8 Preview 6 which is packed with plenty of library updates, a new WASM mode, more source generators, constant performance improvements, and NativeAOT support on iOS.<\/p>\n","protected":false},"author":122298,"featured_media":46612,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7509,756],"tags":[7701],"class_list":["post-46470","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-aspnetcore","category-csharp","tag-dotnet-8"],"acf":[],"blog_post_summary":"<p>We&#8217;re thrilled to announce .NET 8 Preview 6 which is packed with plenty of library updates, a new WASM mode, more source generators, constant performance improvements, and NativeAOT support on iOS.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/46470","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/122298"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=46470"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/46470\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/46612"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=46470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=46470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=46470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}