C# 12 新增功能实操!
<h2 data-tool="mdnice编辑器">前言</h2><p data-tool="mdnice编辑器">今天咱们一起来探索并实践 C# 12 引入的全新功能!</p>
<ul class="list-paddingleft-1" data-tool="mdnice编辑器">
<li><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)">C#/.NET该如何自学入门?</span></span></li>
</ul>
<blockquote data-tool="mdnice编辑器">
<p>注意:使用这些功能需要使用最新的 Visual Studio 2022 版本或安装 .NET 8 SDK 。</p>
</blockquote>
<h2 data-tool="mdnice编辑器">主构造函数</h2>
<p data-tool="mdnice编辑器">主构造函数允许你直接在类定义中声明构造函数参数,并自动生成相应的属性。</p>
<h3 data-tool="mdnice编辑器">主构造函数参数的最常见用途包括:</h3>
<ul class="list-paddingleft-1" data-tool="mdnice编辑器">
<li>作为 base() 构造函数调用的参数。</li>
<li>初始化成员字段或属性。</li>
<li>引用实例成员中的构造函数参数。</li>
</ul>
<h3 data-tool="mdnice编辑器">代码示例</h3>
<p data-tool="mdnice编辑器"><strong>将任何参数放在类型名称后面的括号中:</strong></p>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code> public class CSharp12GrammarExercise<br> {<br> public static void OutputPrint()<br> {<br> var person = new Person("追逐时光者", 30);<br> Console.WriteLine($"{person.Name}, {person.Age}");<br> }<br> }<br><br> public class Person(string name, int age)<br> {<br> public string Name => name;<br> public int Age => age;<br> }<br></code></span></pre>
<p data-tool="mdnice编辑器"><strong>以下代码初始化从主构造函数参数计算的两个只读属性:</strong></p>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code> public class CSharp12GrammarExercise<br> {<br> public static void OutputPrint()<br> {<br> // 创建 Distance 结构体实例<br> Distance distance = new Distance(10, 55);<br> // 访问 Magnitude 和 Direction 属性<br> Console.WriteLine($"Magnitude: {distance.Magnitude},Direction: {distance.Direction}");<br> }<br> }<br><br> public readonly struct Distance(double dx, double dy)<br> {<br> public readonly double Magnitude { get; } = Math.Sqrt(dx * dx + dy * dy);<br> public readonly double Direction { get; } = Math.Atan2(dy, dx);<br> }<br></code></span></pre>
<h2 data-tool="mdnice编辑器">集合表达式</h2>
<p data-tool="mdnice编辑器">集合表达式引入了一种新的简洁语法,用于创建常用集合值。可以使用展开运算符(..)将其他集合内联到这些值中。</p>
<h3 data-tool="mdnice编辑器">下面的示例展示了集合表达式的用法:</h3>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code><br> public static void CollectionExpressions()<br> {<br> // 创建一个数组<br> int[] array = ;<br><br> // 创建一个列表<br> List<string> list = ["one", "two", "three", "five", "追逐时光者"];<br><br> // 创建一个 Span<br> Span<char> span = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'k'];<br><br> // 创建一个交错二维数组<br> int[][] two2D = [, , , ];<br> }<br><br></code></span></pre>
<h3 data-tool="mdnice编辑器">展开运算符(..)示例代码:</h3>
<p data-tool="mdnice编辑器">展开运算符(集合表达式中的 ..)可将其参数替换为该集合中的元素。 参数必须是集合类型。 以下示例演示了展开运算符的工作原理:</p>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code> int[] item0 = ;<br> int[] item1 = ;<br> int[] item2 = ;<br> int[] totalList = [.. item0, .. item1, .. item2];<br> foreach (var element in totalList)<br> {<br> Console.Write($"{element}, ");<br> }<br></code></span></pre>
<p data-tool="mdnice编辑器">没有<code>..</code> 会有异常:</p>
<p><img src="https://img2024.cnblogs.com/blog/1336199/202407/1336199-20240724220622355-1822754860.png" alt="" loading="lazy"></p>
<p>正常输出:</p>
<p><img src="https://img2024.cnblogs.com/blog/1336199/202407/1336199-20240724220633322-83735847.png" alt="" loading="lazy"></p>
<h2 data-tool="mdnice编辑器">内联数组</h2>
<p data-tool="mdnice编辑器">内联数组用于提高应用程序性能,允许在结构体中创建固定大小的数组。虽然你可能不会自己声明内联数组,但当它们通过 <code>System.Span<T></code> 或 <code>System.ReadOnlySpan<T></code> 从运行时 API 暴露出来时,你可以透明地使用它们。内联数组提供与不安全固定大小缓冲区类似的性能特性。</p>
<h3 data-tool="mdnice编辑器">内联数组的声明与下面的结构类似:</h3>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code> <br> public struct Buffer<br> {<br> private int _element0;<br> }<br></code></span></pre>
<h3 data-tool="mdnice编辑器">你可以像使用其他数组一样使用它们:</h3>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code> public static void InlineArrays()<br> {<br> var buffer = new Buffer();<br> for (int i = 0; i < 20; i++)<br> {<br> buffer = i;<br> }<br><br> foreach (var i in buffer)<br> {<br> Console.WriteLine(i);<br> }<br> }<br></code></span></pre>
<h2 data-tool="mdnice编辑器">默认 lambda 参数</h2>
<p data-tool="mdnice编辑器">现在可以为 <span class="wx_search_keyword_wrap">Lambda 表达式的参数定义默认值,语法和规则与将参数的默认值添加到任何方法或本地函数相同。</span></p>
<h3 data-tool="mdnice编辑器">如果 lambda 表达式只有一个输入参数,则括号是可选的:</h3>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code>Func<double, double> testcube = x => x * x * x;<br></code></span></pre>
<h3 data-tool="mdnice编辑器">两个或更多输入参数使用逗号加以分隔:</h3>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code>Func<int, int, bool> testForEquality = (x, y) => x == y;<br></code></span></pre>
<h3 data-tool="mdnice编辑器">可以显式指定类型,如下面的示例所示:</h3>
<p data-tool="mdnice编辑器">注意:输入参数类型必须全部为显式或全部为隐式;否则,便会生成 CS0748 编译器错误!!</p>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code>Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;<br></code></span></pre>
<h2 data-tool="mdnice编辑器">任何类型的别名</h2>
<p data-tool="mdnice编辑器">可以使用 using 别名指令创建任何类型的别名,而不仅仅是命名类型。也就是说,你可以为元组类型、数组类型、指针类型或其他不安全类型创建语义别名。</p>
<h3 data-tool="mdnice编辑器">使用 using 关键字为元组类型创建别名,并进行调用:</h3>
<pre data-tool="mdnice编辑器"><span data-lazy-bgimg="https://mmbiz.qpic.cn/mmbiz_svg/9M0PhLTmTIfnJACqtiacDtgicUibK46DrJf0yV2eBlJzLTu7Us8ia6r6mSzuvaUG83SzbA0G4cfCAccADFY8JONb17w48WkfCR5y/640?wx_fmt=svg&from=appmsg" data-fail="0"><code>using PointTest = (int item1, int item2);<br><br>namespace HelloDotNetGuide.CSharp语法<br>{<br> public class CSharp12GrammarExercise<br> {<br> public static void OutputPrint()<br> {<br> //使用 using 关键字为元组类型创建别名,并进行调用:<br> PointTest point = (10, 20);<br> Console.WriteLine($"输出:Item1={point.Item1}, Item2={point.Item2}");<br> }<br> }<br>}<br></code></span></pre>
<h2 data-tool="mdnice编辑器">参考文章</h2>
<ul class="list-paddingleft-1" data-tool="mdnice编辑器">
<li>详细功能介绍请阅读微软官方文档:<span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)">https://learn.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-12</span></span></li>
<li>文章示例源码地址:<span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)">https://github.com/YSGStudyHards/DotNetGuide/blob/main/DotNetGuidePractice/HelloDotNetGuide/CSharp%E8%AF%AD%E6%B3%95/CSharp12GrammarExercise.cs</span></span></li>
</ul>
<h2 id="activity-name" class="rich_media_title ">DotNetGuide技术社区交流群</h2>
<ul>
<li>DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目框架推荐、求职和招聘资讯、以及解决问题的平台。</li>
<li>在DotNetGuide技术社区中,开发者们可以分享自己的技术文章、项目经验、学习心得、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。</li>
<li>我们致力于构建一个积极向上、和谐友善的.NET技术交流平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。</li>
</ul>
<blockquote>
<p><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><strong>欢迎加入DotNetGuide技术社区微信交流群👪</strong></span></span></p>
</blockquote>
</div>
<div id="MySignature" role="contentinfo">
<blockquote >
<p style='font-family:YouYuan;font-size: 16px;margin: 0 auto 0.01em auto;'><span style='font-size: 17px; '>作者名称:</span>追逐时光者</p>
<p style='font-family:YouYuan;font-size: 16px;margin: 0 auto 0.01em auto;'><span style='font-size: 17px; '>作者简介:</span>一个热爱编程、善于分享、喜欢学习、探索、尝试新事物和新技术的全栈软件工程师。</p>
<p style='font-family:YouYuan;font-size: 16px;margin: 0 auto 0.01em auto;'>
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如果该篇文章对您有帮助的话,可以点一下右下角的【♥推荐♥】,希望能够持续的为大家带来好的技术文章,文中可能存在描述不正确的地方,欢迎指正或补充,不胜感激。
</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/Can-daydayup/p/18321876
頁:
[1]