Skip to content

Commit 5f18237

Browse files
committed
episode 43
1 parent 6a270df commit 5f18237

File tree

2 files changed

+219
-1
lines changed

2 files changed

+219
-1
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
### 2023
1818

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

2123
**八月份**[第 040 期](docs/episode-040.md)
2224

docs/episode-043.md

+216
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# .NET 每周分享第 43 期
2+
3+
## 卷首语
4+
5+
C# 的受欢迎指数超过 Java
6+
7+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/e647d1a3-d4e8-4a7b-bb7b-d4b9d47516b2)
8+
9+
最近的市场调研显示,C# 受欢迎指数正在接近并超越 Java
10+
11+
12+
## 行业资讯
13+
14+
1、[Jetbrains .NET Day 录像](https://blog.jetbrains.com/dotnet/2023/10/02/recordings-jetbrains-dotnet-day-online-23/)
15+
16+
今年 JetBrains 的 .NET Day 活动录像。
17+
18+
2、[VS Code 插件 Dev Kit GA](https://devblogs.microsoft.com/dotnet/csharp-dev-kit-now-generally-available/)
19+
20+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/5af224a3-456f-415a-9aff-96f9d28d7922)
21+
22+
`VS Code``C#` 开发插件 `Dev Kit` 已经可以公开使用。
23+
24+
25+
## 文章推荐
26+
27+
1、[ASP.NET Core 学习路线](https://roadmap.sh/aspnet-core)
28+
29+
![aspnet-core](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/8755c449-d483-4f1e-a9e2-5c065a5f1ebe)
30+
31+
ASP.NET Core 学习路线,包含了四种类型
32+
1. 个人建议
33+
2. 可选
34+
3. 不是严格
35+
4. 不建议
36+
37+
2、[.NET Roll Forward 配置](https://weblog.west-wind.com/posts/2023/Oct/02/Rolling-Forward-to-Major-Versions-in-NET)
38+
39+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/6c228451-85c3-4c2b-9502-b48a24406ee9)
40+
41+
得益于 `.NET` 的兼容性,`.NET 6` 编写的应用程序可以运行在 `.NET 7` 的运行时中,那么该如何配置这个呢?
42+
43+
```xml
44+
<Project Sdk="Microsoft.NET.Sdk">
45+
<PropertyGroup>
46+
<TargetFramework>net7.0-windows</TargetFramework>
47+
<RollForward>LatestMajor</RollForward>
48+
<PropertyGroup>
49+
</Project>
50+
```
51+
52+
除了 `LastMajor` 外,还有
53+
54+
- `Minor`
55+
- `Major`
56+
- `LatestMinor`
57+
58+
等配置。如果是 `Preview` 版本的 SDK 该怎么办呢?比如 `net8.0.0-rc-123419.4`, 则需要配置 `DOTNET_ROLL_FORWARD_TO_PRERELEASE` 环境变量
59+
60+
```powershell
61+
$env:DOTNET_ROLL_FORWARD_TO_PRERELEASE=1
62+
```
63+
64+
65+
3、[序列化中的未知枚举类型](https://gaevoy.com/2023/09/26/dotnet-serialization-unknown-enums-handling-api.html)
66+
67+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/07b66238-7568-4c78-906f-f332337503f5)
68+
69+
在序列化成对象的时候,如果为 Enum (枚举) 类型中不存在的类型时候,通常会抛出异常,那么在不同序列化场景中怎么解决好这个问题呢?分别为 `Newtonsoft`, `System.Text.Json``System.Xml.Serializaton` 等库给出了示例。
70+
71+
4、[如何在 UT 中测试 Logger](https://www.meziantou.net/how-to-test-the-logs-from-ilogger-in-dotnet.htm)
72+
73+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/3bf29b30-cace-48d3-8f1d-c810ddcdb551)
74+
75+
在单元测试用该如何测试 `ILogger` 对象呢?有很多方法,比如
76+
- 使用 `Mock` 库来构造 `ILogger` 实现
77+
- 将所有日志保存在内存中,然后比较
78+
- 将所有日志保存在文件中
79+
80+
第一种方式比较直接,也是大众最为熟悉的方式,第二种就比较不常见,但是有现成的库能够帮助我们实现, `Meziantou.Extensions.Logging.InMemory`
81+
82+
```csharp
83+
// Create the logger
84+
using var loggerProvider = new InMemoryLoggerProvider();
85+
var logger = loggerProvider.CreateLogger("MyLogger");
86+
87+
// Call the method to test
88+
MethodToTest(logger);
89+
90+
// Validate the logs
91+
Assert.Empty(loggerProvider.Logs.Errors);
92+
Assert.Single(loggerProvider.Logs, log => log.Message.Contains("test") && log.EventId.Id == 1);
93+
```
94+
95+
5、[用内存映射文件](https://blog.stephencleary.com/2023/09/memory-mapped-files-overlaid-structs.html)
96+
97+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/5821abf8-8e7d-4d5e-a664-cf184af709ac)
98+
99+
`C#` 这样托管的编程语言中,我们也可以使用访问内存的方式来修改文件内容,这样可以频繁的避免磁盘读写操作,操作系统自会需要的时候才会进行磁盘读写。那么该怎么做呢?
100+
101+
```csharp
102+
using FileStream file = new FileStream(@"tmp.dat", FileMode.Create, FileAccess.ReadWrite,
103+
FileShare.None, 4096, FileOptions.RandomAccess);
104+
using MemoryMappedFile mapping = MemoryMappedFile.CreateFromFile(file, null, 1000,
105+
MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, leaveOpen: true);
106+
using MemoryMappedViewAccessor view = mapping.CreateViewAccessor();
107+
```
108+
109+
这里创建一个`view` 对象,它代表了一个内存指针,这个对象包含了很多个操作方法,通常我们不需要关心,可以直接创建一个 `Overlay` 的对象来操作它
110+
111+
```csharp
112+
public sealed unsafe class Overlay : IDisposable
113+
{
114+
private readonly MemoryMappedViewAccessor _view;
115+
private readonly byte* _pointer;
116+
117+
public Overlay(MemoryMappedViewAccessor view)
118+
{
119+
_view = view;
120+
view.SafeMemoryMappedViewHandle.AcquirePointer(ref _pointer);
121+
}
122+
123+
public void Dispose() => _view.SafeMemoryMappedViewHandle.ReleasePointer();
124+
125+
public ref T As<T>() where T : struct => ref Unsafe.AsRef<T>(_pointer);
126+
}
127+
```
128+
129+
通过它可以方位 `T` 类型的结构
130+
131+
```csharp
132+
public struct Data
133+
{
134+
public int First;
135+
public int Second;
136+
}
137+
138+
using Overlay overlay = new Overlay(view);
139+
ref Data data = ref overlay.As<Data>();
140+
data.First = 1;
141+
data.Second = 2;
142+
```
143+
144+
145+
146+
6、[本地运行 .NET 的 LLM](https://blog.maartenballiauw.be/post/2023/06/15/running-large-language-models-locally-your-own-chatgpt-like-ai-in-csharp.html)
147+
148+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/e08420f3-3655-415e-8869-c1d1ca656134)
149+
150+
随着 LLM 的流行,我们特别希望能够一款运行在本地的大模型。Meta 公司的 LLaMA 开源模型给了这件事情的可能性,SciSharp 项目就是将机器学习和 AI 框架引入到 .NET 生态中。这里介绍如何使用 `C#` 实现本地大模型
151+
152+
153+
## 开源项目
154+
155+
1、[YamlDotNet](https://github.com/aaubry/YamlDotNet)
156+
157+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/6609b43e-cb0a-461a-aad4-a5ebf95e6eae)
158+
159+
很多时候,我们需要进行将 `Yaml``C#` 中的对象进行转换,`YamlDotNet` 库可以很方便的进行序列化和反序列化。
160+
161+
162+
```csharp
163+
using YamlDotNet.Serialization;
164+
using YamlDotNet.Serialization.NamingConventions;
165+
...
166+
167+
var person = new Person
168+
{
169+
Name = "Abe Lincoln",
170+
Age = 25,
171+
HeightInInches = 6f + 4f / 12f,
172+
Addresses = new Dictionary<string, Address>{
173+
{ "home", new Address() {
174+
Street = "2720 Sundown Lane",
175+
City = "Kentucketsville",
176+
State = "Calousiyorkida",
177+
Zip = "99978",
178+
}},
179+
{ "work", new Address() {
180+
Street = "1600 Pennsylvania Avenue NW",
181+
City = "Washington",
182+
State = "District of Columbia",
183+
Zip = "20500",
184+
}},
185+
}
186+
};
187+
188+
var serializer = new SerializerBuilder()
189+
.WithNamingConvention(CamelCaseNamingConvention.Instance)
190+
.Build();
191+
var yaml = serializer.Serialize(person);
192+
System.Console.WriteLine(yaml);
193+
// Output:
194+
// name: Abe Lincoln
195+
// age: 25
196+
// heightInInches: 6.3333334922790527
197+
// addresses:
198+
// home:
199+
// street: 2720 Sundown Lane
200+
// city: Kentucketsville
201+
// state: Calousiyorkida
202+
// zip: 99978
203+
// work:
204+
// street: 1600 Pennsylvania Avenue NW
205+
// city: Washington
206+
// state: District of Columbia
207+
// zip: 20500
208+
```
209+
210+
211+
2、[Source Code Generator Playgroud](https://github.com/davidwengier/SourceGeneratorPlayground)
212+
213+
![image](https://github.com/DotNETWeekly-io/DotNetWeekly/assets/11272110/b2b40480-d541-459f-a6a3-4520738bf9bd)
214+
215+
216+
Source Generator 是 C# 的引入和的新功能,那么这个在线工具可以测试该功能。

0 commit comments

Comments
 (0)