C#(发音为“C sharp”)是由Microsoft开发的一种通用的面向对象的编程语言。它广泛用于构建各种类型的软件应用程序,从桌面应用程序到 Web 服务、游戏和移动应用程序。 C# 是 .NET 框架的一部分,它为开发人员提供了一组丰富的库和工具。
C# 最初于 2000 年推出,此后经历了多个版本的发展,每次迭代都引入了新功能和改进。它与 C 和 C++ 等语言有相似之处,但它也融合了 Java 等语言的概念。
C# 以其简单性、可读性和可伸缩性而闻名,使其成为小型项目和大型企业应用程序开发人员的热门选择。它支持现代编程范式,例如面向对象、命令式、函数式和面向组件的编程。此外,C# 通常与其他技术结合使用,例如用于 Web 开发的 ASP.NET 和用于跨平台移动开发的 Xamarin。
使用 C#13,我们不仅仅是在升级一种语言;我们正在拥抱一种思维方式——一种将过去的智慧与未来的兴奋融为一体的哲学。这就像踏上了一场惊心动魄的冒险,每个新功能都是一个等待发现的发现。
因此,当我们开始使用 C#13 及其新功能的旅程时,让我们记住,编码不仅仅是一种技能,而是一种艺术形式。让我们为我们的项目注入创造力和激情,让我们在不断发展的 C# 故事中写下我们自己的篇章。
C# 13 新功能侧重于灵活性和性能。
让我们来谈谈这些新功能:
1。定义
参数修饰符不限于数组类型。
参数/参数集合是使用 params 修饰符声明的参数。
2。新增(使用 C# 13)
params 修饰符现在支持:
使用 Add() 方法,以及来自 System.Collections.Generic 的相关接口,例如:
Note :编译器管理接口参数的存储。
internal class Program {
//--MAIN
static void Main(string[] args) {
Console.WriteLine(Sum(1, 2, 3, args.Length));
}
//--NEW-SCHOOL PARAMS COLLECTIONS
private static int SumNew(params ReadOnlySpan<int> values) {
int sum = 0;
foreach (var item in values) {
sum += item;
}
return sum;
}
//--OLD-SCHOOL PARAMS ARRAY
private static int SumOld(params int[] values) {
int sum = 0;
foreach (var item in values) {
sum += item;
}
return sum;
}
}
3。标杆
使用 ReadOnlySpan 参数与数组参数比较方法
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkRunner.Run<BM>();
[MemoryDiagnoser(false)]
[HideColumns("RatioSD", "Alloc Ratio")]
public class BM {
private decimal _value = 500m;
[Benchmark]
public decimal CallSumArray() => SumArray(1m, 100m, 200m, 300m, 400m, _value);
[Benchmark(Baseline = true)]
public decimal CallSumSpan() => SumSpan(1m, 100m, 200m, 300m, 400m, _value);
private static decimal SumArray(params decimal[] values) {
decimal sum = 0;
foreach (var item in values) {
sum += item;
}
return sum;
}
private static decimal SumSpan(params ReadOnlySpan<decimal> values) {
decimal sum = 0;
foreach (var item in values) {
sum += item;
}
return sum;
}
}
基准测试 SumArray 与 SumSpan
结果:
.NET 9 运行时包括用于线程同步的新类型:System.Threading.Lock 类型。
System.Threading.Lock 类型通过其 API 提供更好的线程同步。
二-1。例
using System;
using System.Threading.Tasks;
public class Account
{
// Use `object` in versions earlier than C# 13
private readonly System.Threading.Lock _balanceLock = new();
private decimal _balance;
public Account(decimal initialBalance)
=> _balance = initialBalance;
public decimal Debit(decimal amount)
{
if (amount < 0)
{
throw new ArgumentOutOfRangeException(nameof(amount),
"The debit amount cannot be negative.");
}
decimal appliedAmount = 0;
lock (_balanceLock)
{
if (_balance >= amount)
{
_balance -= amount;
appliedAmount = amount;
}
}
return appliedAmount;
}
public void Credit(decimal amount)
{
if (amount < 0)
{
throw new ArgumentOutOfRangeException(nameof(amount),
"The credit amount cannot be negative.");
}
lock (_balanceLock) { _balance += amount;}
}
public decimal GetBalance()
{
lock (_balanceLock){ return _balance;}
}
}
class AccountTest
{
static async Task Main()
{
var account = new Account(1000);
var tasks = new Task[100];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Run(() => Update(account));
}
await Task.WhenAll(tasks);
Console.WriteLine($"Account's balance is
{account.GetBalance()}");
// Output:// Account's balance is 2000
}
static void Update(Account account)
{
decimal[] amounts = [0, 2, -3, 6, -2, -1, 8, -5, 11, -6];
foreach (var amount in amounts)
{
if (amount >= 0)
{
account.Credit(amount);
}
else
{
account.Debit(Math.Abs(amount));
}
}
}
}
解释:
此 C# 代码片段演示了帐户类的简单实现,该类管理银行帐户的余额,同时使用锁确保线程安全。让我们分解一下关键组件:
字符字面表示单个字符,并由引号中的字符组成,如“a”。
以前,使用 \u001b 或 \x1b。
但是不建议使用 \x1b,因为如果 1b 后面的下一个字符是有效的十六进制数字,则这些字符将成为转义序列的一部分。
新增(使用 C# 13)
Example :
string path = "\\eUsers\\eJohnDoe\\eDocuments\\eFile.txt";
Console.WriteLine(path);
Output :
C:\\Users\\JohnDoe\\Documents\\File.txt
以前的行为是编译器为方法组构造完整的候选方法集。
如果需要自然类型,则从完整的候选方法集确定自然类型。 新的转义序列
新增(使用 C# 13)
V.1-BEFORE(C# 13 之前版本)
^ 运算符不能在对象初始值设定项表达式中使用,并且需要从前面为元素编制索引。
V.2-新增(使用 C# 13)
现在,您可以直接在对象初始值设定项中使用 ^ 运算符,这样可以更自然、更简洁地从末尾索引元素。
主要优点
V-3的。示例:BEFORE(在 C#13 之前)
public class TimerRemaining {
public int[] buffer = new int[10];
}
var countdown = new TimerRemaining()
{
buffer = new int[10] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }
};
for (int i = 0; i < countdown.buffer.Length; i++)
{
Console.WriteLine($"buffer[{i}] = {countdown.buffer[i]}");
}
Output:
buffer[0] = 9
buffer[1] = 8
buffer[2] = 7
buffer[3] = 6
buffer[4] = 5
buffer[5] = 4
buffer[6] = 3
buffer[7] = 2
buffer[8] = 1
buffer[9] = 0
解释:
在 C# 13 之前,每个元素都必须从一开始就按顺序显式分配,这使得代码在顺序颠倒时更长且更难阅读。
V-3-现在(使用 C#13)
public class TimerRemaining {
public int[] buffer = new int[10];
}
var countdown = new TimerRemaining() {
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2,
[^4] = 3,
[^5] = 4,
[^6] = 5,
[^7] = 6,
[^8] = 7,
[^9] = 8,
[^10] = 9
}
};
for (int i = 0; i < countdown.buffer.Length; i++)
{
Console.WriteLine($"buffer[{i}] = {countdown.buffer[i]}");
}
Output:
buffer[0] = 9
buffer[1] = 8
buffer[2] = 7
buffer[3] = 6
buffer[4] = 5
buffer[5] = 4
buffer[6] = 3
buffer[7] = 2
buffer[8] = 1
buffer[9] = 0
扩展类型不在当前预览版中。
VI-示例:
public class Person()
{
public required string GivenName { get; init; }
public required string SurName { get; init; }
public required Organization Organization { get; init; }
}
public class Organization()
{
public required string Name { get; init; }
public required List<Team> Teams { get; init; }
}
public class Team()
{
public required string TeamName { get; init; }
public required Person Lead { get; init; }
public required IEnumerable<Person> Members { get; init; }
}
扩展方法:
public implicit extension PersonExtension for Person
{
public bool IsLead
=> this.Organization
.Teams
.Any(team => team.Lead == this);
}
解释-PersonExtension 类:
public explicit extension Lead for Person
{
public IEnumerable<Team> Teams
=> this.Organization
.Teams
.Where(team => team.Lead == this);
}
解释-引线延伸方法:
public implicit extension OrganizationExtension for Organization
{
private static Organization ourOrganization = new Organization("C# Design");
public static Person CreatePerson(string givenName, string surName)
=> new(givenName, surName, ourOrganization);
}
Explanation-OrganizationExtension 类: