C# 成为年度语言? 这里有一个有趣的不同的观点。
在过去的一段时间,.NET
社区最大的新闻是 C#
被 Tiobe 评选为 2023 年度编程语言。几乎所有的媒体都在欢呼雀跃,那么事实真的如此吗?
- Tiobe 评选的标准是增加量
- 结果并不会改变立刻任何事情
- Tiobe 的选择的可靠性不高
在 Microsoft.Extensions.Primitives
包中有一个类型是 StringValues
, 它可以用在表示 HTTP
Header 中,可以表达三种情况,
- 没有 Header
- 单个 Header
- 多个 Header
那么在 ASP.NET Core
中,该如何表示这个对象呢?
- 朴素表达方式
使用 Dictionary<string, string[]>
类型表达,因为上述三种情况都可以表示,但是这个存在两个问题:
- 大部分情况下,只有一个值,但是还是需要多个情况
- 将单个值存储为一个数组,增加内存分配
NameValueCollection
在 ASP.NET
中使用 NameValueCollection
类型,但是它本质还是使用 ArrayList
存储内容, 所以还是不够优雅。
在 StringValues
使用一个 object
表示上述的三种情况,也是一个 readonly struct
类型。
.NET 8 在 Random
类中提供了一些新的方法,比如
- GetItems
当我们在一个集合中随机选择一定数量时候,可以使用 GetItems
, 比如 Random.Shard.GetItems
。
- Shuffle
如果对一个集合进行混洗,可以使用 Shuffle
, 比如 Random.Shard.Shuffle
。
在 IHost
中,在执行 Run
方法的时候,会获取所有的注册的 IHostedService
取出来,然后执行 StartAsync
方法。要注意的是这个方法是顺序执行的,在 .NET 8
中,可以设置 HostOption
的 ServicesStartConcurrently
和 ServicesStopConcurrently
方法让启动或者停止并行执行。
new HostBuilder()
.ConfigureServices(service =>
{
service.Configure<HostOptions>(options =>
{
options.ServicesStartConcurrently = true;
options.ServicesStopConcurrently = true;
});
service.AddHostedService<FooService>();
service.AddHostedService<BarService>();
})
.Build()
.Run();
internal class FooService : IHostedService
{
public async Task StartAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Start Foo");
await Task.Delay(2000);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Stop Foo");
await Task.Delay(2000);
}
}
internal class BarService : IHostedService
{
public async Task StartAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Start Bar");
await Task.Delay(1000);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Stop Bar");
await Task.Delay(1000);
}
}
C# 支持查看 JIT
生成的机器代码,那么该如何查看它们呢?有三种方法
- DOTNET_JitDisasm="Method"
Foo.Bar();
class Foo
{
public static void Bar()
{
Console.WriteLine("Hello World!");
}
}
如果设置 DOTNET_JitDisasm="BAR"
,那么在执行这个方法的时候,就能看到生成 JIT
代码
- Disasmo
Disasmo
是 Visual Studio 的插件,用来查看生成的 JIT 代码。
- Sharplab
Sharplab 是一个非常有用的 Web 站点,它可以对相关的代码生成相应的 JIT 代码方便查看。
DTO
和 POCO
是在开发工程中经常遇到的概念,那么它们区别是怎样的呢?
- DTO
DTO 是 Data Transfer Object
的简写,它表明只是传递数据,而不包含逻辑和行为。在 C# 中就是只有只有属性,而不是有方法或者属性的注解。
- POCO
POCO 是 Plain Old CLR Object
的简称,它表明这个类不依赖任何第三方的库或者框架。
在今年开始的时候,GitHub
爆火了 ”十亿行挑战" 活动。从原先的 Java
语言到所有开发语言。在 .NET
范围内,目前最快记录是 1.297
秒,作者介绍了自己的优化之路。
在一些大型 .NET
项目中,常常会遇到依赖冲突的问题,比如
- 无法解析依赖的一致性问题
- 依赖包不包含适合项目的资源包
- 依赖的包版本大于最终解析版本
等等问题,Nuget
团队和 MSR 团队合作,推出了 NuGetSolver
中 Visual Studio
插件,它可以解决上述的问题。但是目前有一些限制
- 只支持
nuget.org
源 - 不支持多个源
- 不支持自动更新版本
- 不支持 preview 版本
package.config
等老式版本不支持- 只支持编译依赖冲突
2、Rx.NET
Rx.NET
是一个开源的 .NET
事件库,可以帮助实现响应式编程,这样你的代码只需要响应对应的事件。
using System.Reactive.Linq;
IObservable<long> ticks = Observable.Timer(
dueTime: TimeSpan.Zero,
period: TimeSpan.FromSeconds(1));
ticks.Subscribe(tick => Console.WriteLine($"Tick {tick}"));
Console.ReadKey();
微软推出了 MSTest Runner
这个测试框架,它更加轻量级,测试更快并且提供更加便携的测试机制。主要修改两个地方
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Enable the MSTest runner, this is an opt-in feature -->
<EnableMSTestRunner>true</EnableMSTestRunner>
<!-- We need to produce an executable and not a DLL -->
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MSTest" Version="3.2.0" />
</ItemGroup>
</Project>
这样只需要执行生成的 exe
就可以运行单元测试。