This page shows the source for this entry, with WebCore formatting language tags and attributes highlighted.

Title

C# 11 Features

Description

The articles <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features" author="Oleg Kyrylchuk" source="">Twelve C# 11 Features</a> and <a href="https://devblogs.microsoft.com/dotnet/welcome-to-csharp-11/" author="Mads Torgersen" source="Microsoft .NET Blog">Welcome to C# 11</a> provide an excellent overview with examples of new features in C# 11, available with .NET 7.0. I include my own notes below. <h>Interesting and obviously useful</h> "Obvious" to me, at least. The terms link to examples in one of the articles linked above. <dl> <a href="https://devblogs.microsoft.com/dotnet/welcome-to-csharp-11/#utf-8-string-literals">Native UTF-8 Strings</a> You can now append <c>u8</c> to the end of a literal string to make it <a href="https://devblogs.microsoft.com/dotnet/welcome-to-csharp-11/#utf-8-string-literals">UTF-8</a> instead of the system-standard UTF-16. For example, <c>"Test string"u8</c> will be encoded by the compiler as UTF-8 and will have the type <c>ReadOnlySpan<byte></c>. <a href="https://devblogs.microsoft.com/dotnet/welcome-to-csharp-11/#raw-string-literals">Raw Strings (Here-Doc)</a> <div>C# finally supports "here documents" (which have been supported in other languages like <a href="https://perlmaven.com/here-documents">Perl</a> or <a href="https://www.phptutorial.net/php-tutorial/php-heredoc/">PHP</a> for a long time). In C#, they're called <a href="https://devblogs.microsoft.com/dotnet/welcome-to-csharp-11/#raw-string-literals">raw string literals</a> and,<ul>they begin and end with at least three double-quotes can be multi-line can contain unescaped everything (unless you have three double-quotes in a row, in which case, you just add more double quotes to the fences at the beginning and end) support interpolation and also automatically trim left indenting.</ul> Finally, you can just pass a formatted and indented JSON into C# code, interpolate some variables, and do it all without escaping anything!<fn></div> <a href="https://devblogs.microsoft.com/dotnet/welcome-to-csharp-11/#abstracting-over-static-members">Abstracting over static members</a> <div><bq>In fact .NET 7 comes with a new namespace <c>System.Numerics</c> chock-full of math interfaces, representing the different combinations of operators and other static members that you’d ever want to use. [...] All the numeric types in .NET now implement these new interfaces – and you can add them for your own types too! So it’s now easy to write numeric algorithms once and for all – abstracted from the concrete types they work on – instead of having forests of overloads containing essentially the same code.</bq> See <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-static-abstract-members-in-interfaces">here</a> for an example of using generic parameters in <c>operators</c>, or <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-generic-math">Generic Math</a> for an example that uses some of the new interfaces, like <c> IAdditionOperators</c> and <c>ISubtractionOperators</c>. In that vein, there are a lot more interfaces that support generalized computation, like <a href="https://learn.microsoft.com/en-us/dotnet/api/system.ispanparsable-1?view=net-7.0">ISpanParsable<tself> Interface</a>, which <iq>[d]efines a mechanism for parsing a span of characters to a value.</iq></div> <a href="https://devblogs.microsoft.com/dotnet/welcome-to-csharp-11/#required-members">Required members</a> <div><bq>Another ongoing theme that we’ve been working on for several releases is improving object creation and initialization. C# 11 continues these improvements with required members.</bq></div> <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-generic-attributes">Generic Attributes</a> You can now make attributes generic <i>and</i> use a generic constraint to limit which types may be passed as type parameters (enforced by the compiler, rather than at runtime). E.g. <c>[Generic<mytype>]</c> declared an attribute of type <c>GenericAttribute</c> parametrized with <c>MyType</c>. <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-extended-nameof-scope">Extended <c>nameof</c> Scope</a> This seems like a small one, but it's a welcome improvement. You can now use <c>nameof</c> with <iq>method parameter[s] in an attribute on the method or parameter declaration.</iq> <c>StringSyntaxAttribute</c> <hl>[Added on 03.12.2022]</hl> This one is not technically part of C#---it's actually included in .NET 7---but it's worth an honorable mention. You can now decorate a parameter to indicate the string-syntax that it supports. This allows IDEs to provide string-syntax-specific code-completion, highlighting, and error-handling. A good example is, of course, for <i>regular expression patterns</i>. While Rider and ReSharper have provided this support for certain constructors and methods (e.g. <c>RegEx</c> or <c>DateTime.Format</c>), this is a welcome standardization that gives your own APIs the same star treatment. The post <a href="https://bartwullems.blogspot.com/2022/12/net-7-stringsyntaxattribute.html">What does the StringSyntaxAttribute do?</a> includes a list of the syntaxes supported out-of-the-box. The post <a href="https://www.alwaysdeveloping.net/dailydrop/2022/03/28-stringsyntaxattribute/">StringSyntaxAttribute for syntax highlighting</a> provides examples and screenshots. </dl> <h>Niche Additions</h> A few that seem a bit dubious, but are, I guess, welcome additions, and will be useful to someone are, <dl> <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-list-patterns">List patterns</a> You can do some wild matching with these (i.e. <c>numbers is [_, >= 2, _, _]</c> returns <c>true</c> if <c>numbers</c> is a four-element list where the second element is greater than or equal to 2. <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-newlines-in-string-interpolation-expressions">Newslines in string-interpolation patterns</a> I guess it's nice that you can format complex variables inside an interpolated string, but I still think that you should just make a local variable instead. That would be more readable, in any case. <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-auto-default-structs">Auto-default Structs</a> This will allow you to define structs without being so pedantic about defining the constructor. <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-an-unsigned-right-shift-operator">Unsigned Right-shift Operator</a> I know I'm almost certainly not going to use this one, but it nicely rounds out the support offered with the new <c>System.Numerics</c> interfaces and the increased generality offered by abstracting over static members (linked above). <a href="https://blog.okyrylchuk.dev/twelve-csharp-11-features#heading-file-scoped-types">File-scoped types</a> This seems kind of like an analog to unexported types declared in TypeScript, but I don't really see myself using them very much until we get the <a href="{app}view_article.php?id=4553">type declaration from TypeScript</a> as well. <a href="https://stevetalkscode.co.uk/regex-source-generator">Source-generated regular expressions</a> <div>This feature leverages the <a href="https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview">source-generation</a> that's been available since <a href="https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/">.NET 5</a> to avoid JIT for regular expressions by generating code for it directly. It's really great to see the .NET team getting mileage out of the features they're adding (I'm sure this isn't a coincidence). For another example of source-generation, see <a href="https://www.meziantou.net/generate-pinvoke-code-for-win32-apis-using-a-source-generator.htm" author="Gérald Barré" source="Meziantou's Blog">Generating PInvoke code for Win32 apis using a Source Generator</a>, which explains how to use Microsoft's NuGet package <c>Microsoft.Windows.CsWin32</c> to easily generate source for any Win32 API or type---no more writing this stuff manually!</div> </dl> <hr> <ft>Check out the following animation of converting an escaped string to a raw string in Rider (from the post <a href="https://blog.jetbrains.com/dotnet/2022/12/07/rider-2022-3/" author="Sasha Ivanova" source="The .NET Tools Blog">Rider 2022.3: Support for .NET 7 SDK, the Latest From C#11, Major Performance Improvements, and More!</a>: <img src="https://blog.jetbrains.com/wp-content/uploads/2022/12/cs-to-raw-strings.gif" style="width: 500px"></ft>