Skip to content

Commit 2785d62

Browse files
committed
episode 41
1 parent 31bcc29 commit 2785d62

File tree

2 files changed

+199
-1
lines changed

2 files changed

+199
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
### 2023
1818

19-
**八月份**[第 040 期](docs/episode-040.md) :high_brightness:
19+
**九月份**[第 041 期](docs/episode-041.md) :high_brightness:
20+
21+
**八月份**[第 040 期](docs/episode-040.md)
2022

2123
**七月份**[第 039 期](docs/episode-039.md) | [第 038 期](docs/episode-038.md)
2224

docs/episode-041.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# .NET 每周分享第 41 期
2+
3+
## 卷首语
4+
5+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/c5b23ca3-e0d8-4552-b4a8-02f10763333e)
6+
7+
最近 `.NET` 社区的大新闻是微软将在明年退役 `Visual Studio for Mac` 这个产品,该消息在社区的引发了巨大的讨论。
8+
9+
## 行业资讯
10+
11+
1、[Rider 65% 折扣](https://blog.jetbrains.com/dotnet/2023/09/01/65-off-rider/)
12+
13+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/103705ae-de2e-4378-8dba-41f4beb3422c)
14+
15+
当微软宣布不再支持 `Visual Studio for Mac` 之后,`JetBrains` 就立马宣布旗下 `Rider` IDE 进行 65% 的折扣销售,可谓是**杀人诛心**
16+
17+
18+
## 文章推荐
19+
20+
1、[Rust 代码运行在 .NET CLR 中](https://fractalfir.github.io/generated_html/rustc_codegen_clr_v0_0_1.html)
21+
22+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/331352cb-bf8e-4faf-8536-0bbe42a67dcf)
23+
24+
这是一篇非常有意思的博客,作者尝试了将 Rust 代码生成的结果运行在 .NET CLR 上
25+
26+
2、[使用 String.Globalization.StringInfo 计算 Unicode 字符的长度](https://khalidabuhakmeh.com/measuring-unicode-string-lengths-with-csharp)
27+
28+
[image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/49c5fc63-029b-4a18-836e-5a67fddb21b2)
29+
30+
在处理 `Unicode` 字符串的时候,我们需要知道字符串所占用的字节长度。尤其是涉及到 Emoji 时候,它有时候是多个 Unicode 字符串拼接而成,所以在 C# 中我们可以通过 `String.Globalization.StringInfo.GetNextTextElementLength` 方法来获得字符所占用的字节数量。
31+
32+
```csharp
33+
using System.Globalization;
34+
35+
var characters = new[] { "a", "1", "👩‍🚀", "", "👨‍👩‍👧‍👦", "" };
36+
37+
var lengths = characters.Select(c => (value: c, length: StringInfo.GetNextTextElementLength(c)));
38+
39+
foreach(var (val, length) in lengths)
40+
{
41+
Console.WriteLine($"{val} (length: {length}");
42+
}
43+
```
44+
45+
46+
3、[Visual Studio 9 个隐藏功能](https://blog.elmah.io/9-hidden-features-in-visual-studio-that-you-may-not-know/)
47+
48+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/14e33986-066f-479e-ba70-7766358ebd5a)
49+
50+
`Visual Studio` 是一款广泛使用的 IDE,那么对于 Visual Studio 还有一些隐藏的功能。
51+
52+
1. Drag & Drop 添加工程应用
53+
2. GitHub Action 在 Visual Studio 解决方案视图
54+
3. CPU/Memory Profiler: 通过在不同断点之间开启 CPU profile
55+
4. 拷贝带缩进
56+
5. Visual Studio 通常会保存上次的 profile,但是 Visual Studio 支持在启动的时候配置不同的 profile.
57+
6. 清理不同的 Azure Functional 工具
58+
7. 内嵌展示诊断信息
59+
8. 智能 JSON 校验
60+
9. 不同事件播放不同声音
61+
62+
63+
4、[HttpClient DelegatingHandler](https://www.youtube.com/watch?v=goxI3rOMnmY&ab_channel=NickChapsas)
64+
65+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/52988af4-6a9b-4867-8843-2f05d86cc426)
66+
67+
我们都知道 `ASP.NET Core` 通过中间件的方式,处理一个个请求,对于定制化的业务逻辑,我们可以编写自己的中间件。同样的在 `HttpClient` 类中,我们 `DelegateHandler` 也可以当作中间件,可以对client 发出的请求进行定制化处理,比如缓存请求。
68+
69+
```csharp
70+
internal class CacheHttpMessageHandler : DelegatingHandler
71+
{
72+
private readonly IMemoryCache _cache;
73+
public CacheHttpMessageHandler(IMemoryCache cache)
74+
{
75+
_cache = cache;
76+
}
77+
78+
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
79+
{
80+
var queryString = HttpUtility.ParseQueryString(request.RequestUri.Query);
81+
var key = queryString["city"];
82+
if (_cache.TryGetValue<string>(key, out var content))
83+
{
84+
return new HttpResponseMessage(System.Net.HttpStatusCode.NotModified)
85+
{
86+
Content = new StringContent(content)
87+
};
88+
}
89+
90+
var response = await base.SendAsync(request, cancellationToken);
91+
content = await response.Content.ReadAsStringAsync();
92+
_cache.Set<string>(key, content, TimeSpan.FromSeconds(10));
93+
return response;
94+
}
95+
}
96+
```
97+
98+
那么可以将它注册到容器中
99+
```csharp
100+
IServiceCollection service = new ServiceCollection();
101+
102+
service.AddMemoryCache();
103+
service.AddTransient<CacheHttpMessageHandler>();
104+
service.AddHttpClient("httpbin")
105+
.AddHttpMessageHandler<CacheHttpMessageHandler>();
106+
107+
IServiceProvider provider = service.BuildServiceProvider();
108+
109+
var httpClientFactory = provider.GetService<IHttpClientFactory>();
110+
111+
HttpClient httpClient = httpClientFactory.CreateClient("httpbin");
112+
113+
for (int i = 0; i < 20; i++)
114+
{
115+
using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://httpbin.org/get?city=beijing");
116+
using var response = await httpClient.SendAsync(httpRequestMessage);
117+
Console.WriteLine(response.StatusCode);
118+
await Task.Delay(TimeSpan.FromSeconds(1));
119+
}
120+
```
121+
122+
5、[.NET 生成时 AI ](https://devblogs.microsoft.com/dotnet/demystifying-retrieval-augmented-generation-with-dotnet/)
123+
124+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/90781485-ccbf-4153-8c42-7e25410e7ca2)
125+
126+
这是一份来自 `Stephen Toub` 的文章,介绍了如何使用 `Semantic Kernal``Azuer OpenAI` 来一步步创建一个 `.NET` 的对话应用程序。
127+
128+
6、[.NET Runtime Bug](https://www.youtube.com/watch?v=1oR7L6kHnCI&ab_channel=NickChapsas)
129+
130+
131+
```csharp
132+
using System.Collections;
133+
134+
IStructuralEquatable one = new ValueTuple<int, int, int, int, int>(1, 2, 3, 4, 5);
135+
IStructuralEquatable two = new ValueTuple<int, int, int, int, int>(1, 2, 3, 5, 5);
136+
137+
Console.WriteLine(one.Equals(two, EqualityComparer<int>.Default));
138+
```
139+
140+
上面这段代码的返回输出是什么?应该是 `false`,因为第四个元素的值不一样,但是在目前的 `.NET` SDK 中,编译出来的结果是 `true`。这是 `.NET` BCL 的 bug,因为 `Tuple` 类型的 `Equal` 方法跳过了第四个元素。
141+
142+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/ac8ed09f-aea6-4334-b94b-f9d8ad99a389)
143+
144+
目前 `Fix` PR 已经合并。
145+
146+
147+
## 开源项目
148+
149+
1、[ConsoleTables](https://github.com/khalidabuhakmeh/ConsoleTables)
150+
151+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/81759be7-46cc-45a1-8f84-6c2b9eead986)
152+
153+
`C#` 的控制台应用程序中,我们有时候需要输出一些表格的内容来更加直观的展示内容。`ConsoleTables` 这个开源库可以帮助我们很方便的输出。使用方法也是非常简单
154+
155+
```csharp
156+
var table = new ConsoleTable("one", "two", "three");
157+
table.AddRow(1, 2, 3)
158+
.AddRow("this line should be longer", "yes it is", "oh");
159+
table.Write();
160+
```
161+
162+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/6d800acf-ab05-4085-8954-f2aba5becf7b)
163+
164+
淡然可以控制输出表格的样式
165+
166+
```csharp
167+
var rows = Enumerable.Repeat(new Something(), 10);
168+
ConsoleTable
169+
.From<Something>(rows)
170+
.Configure(o => o.NumberAlignment = Alignment.Right)
171+
.Write(Format.Alternative);
172+
173+
```
174+
175+
2、[Visual Studio 中预览图片](https://github.com/MadsKristensen/ImagePreview)
176+
177+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/727cbd7a-5a17-406d-bee5-f876c102bf7a)
178+
179+
这是 Visual Studio 的可以插件,当你把鼠标放在上面的时候,它会根据图片的地址获取,然后以缩略图的方式展示出来。支持下面的图片路径格式
180+
181+
- 绝对 URI 地址
182+
- 相对 URI 地址
183+
- 文件路径
184+
- 数据 URI
185+
- 包 URI
186+
187+
3、[CSharpier](https://github.com/belav/csharpier)
188+
189+
190+
`CSharpier` 是一个 `.NET` 的代码格式化工具。首先安装工具
191+
192+
```
193+
dotnet tool install csharpier -g
194+
```
195+
196+
然后使用 `dotnet charpier .` 命令可以格式化相应的 `.NET` 项目。

0 commit comments

Comments
 (0)