|
| 1 | +# .NET 每周分享第 36 期 |
| 2 | + |
| 3 | +## 卷首语 |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +今年 [Microsoft Build](https://build.microsoft.com/en-US/home) 大会在 5 月份召开,其中最重要的关键词就是 `AI` 和 `Copliot`。当然对于 `.NET`也是有涉及,主要是在性能上的提升,还介绍了 Windows11 的 `DevHome`, 可以非常方便开发者进行环境搭建,开发机器性能监控和 `GitHub` 看板功能。 |
| 8 | + |
| 9 | +## 行业资讯 |
| 10 | + |
| 11 | +1、[Fleet C# 支持更新](https://blog.jetbrains.com/dotnet/2023/05/04/csharp-support-in-fleet-solution-view-unit-testing-and-more/) |
| 12 | + |
| 13 | + |
| 14 | + |
| 15 | +JetBrains 更新了 Fleet 对 C# 支持的特性,主要包括 |
| 16 | + |
| 17 | +1. 解决方案视图 |
| 18 | +2. Build/Rebuild/Clean 操作 |
| 19 | +3. 单元测试 |
| 20 | + |
| 21 | +2、[Visual Studio UI 更新](https://devblogs.microsoft.com/visualstudio/visual-studio-ui-refresh/) |
| 22 | + |
| 23 | + |
| 24 | + |
| 25 | +Visual Studio 团队打算遵循 `Fluent UI` 的为 VS 重新设计 UI 界面,主要处于下面三个考虑 |
| 26 | + |
| 27 | +- 一致性 |
| 28 | +- 可访问行 |
| 29 | +- 效率 |
| 30 | + |
| 31 | +下拉菜单对比: |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | +2、[Visual Studio Sticky 滚动](https://devblogs.microsoft.com/visualstudio/sticky-scroll-stay-in-the-right-context/) |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | +`Sticky` 是一个非常使用的功能,非常类似在 `Excel` 中将表头固定,然后向下翻动行。在编写代码的时候,有很多 `for`, `foreach` 等循环,如果循环体非常长,或者存在嵌套循环,那么这个功能还是非常有用的。 |
| 40 | + |
| 41 | +## 文章推荐 |
| 42 | + |
| 43 | +1、[NET 8 中 NativeAOT 编译](https://www.youtube.com/watch?v=G5RiC9qQNvw&ab_channel=NickChapsas) |
| 44 | + |
| 45 | + |
| 46 | + |
| 47 | +.NET 8 中支持 `Native AOT` 编译,也就是说编译出来的应用程序就是原生的应用程序,而不是需要 `.NET` 运行时才能的执行,跟 `Rust` 和 `Go` 一样。 |
| 48 | +只需要在 `csproj` 文件中配置 `<publishAot>true<publishaot>` 即可。 |
| 49 | + |
| 50 | +2、[C# IDisposable 和 Go defer 的区别](https://blog.cellfish.se/2023/05/go-for-c-developers-defer-is-not.html) |
| 51 | + |
| 52 | + |
| 53 | + |
| 54 | +`C#` 和 `Go` 中有两个非常相似的功能叫,分别为 `IDisposable` 和 `defer`, 通常是在方法执行完毕后,执行一些清理工作。比如关闭开打的文件流和网络 `socket`。但是这两者还是有一些区别 |
| 55 | + |
| 56 | +- `IDisposable` 并不保证的 `Dispose` 方法肯定被调用,除非放在 `using` 的语句块中,而且变量离开了作用域就会执行。 |
| 57 | +- `defer` 只会在函数 `return` 之后才会执行,而且肯定会执行。 |
| 58 | + |
| 59 | +3、[正确的输出日志](https://www.youtube.com/watch?v=PvQGVmozCdU&ab_channel=NickChapsas) |
| 60 | + |
| 61 | + |
| 62 | + |
| 63 | +日志是应用程序中不可或缺的的组成部分,随着 `Microsoft.Extensions.Logging` 扩展包推出,不同的日志输出源只要配置好 `LoggerProvider` 就可以了。 `ILogger` 的 `LogInformation`, `LogWarning` 方法就是公开的接口,方法签名是这样的 |
| 64 | + |
| 65 | +```csharp |
| 66 | +/// <summary> |
| 67 | +/// Formats and writes an informational log message. |
| 68 | +/// </summary> |
| 69 | +/// <param name="logger">The <see cref="ILogger"/> to write to.</param> |
| 70 | +/// <param name="message">Format string of the log message in message template format. Example: <c>"User {User} logged in from {Address}"</c></param> |
| 71 | +/// <param name="args">An object array that contains zero or more objects to format.</param> |
| 72 | +/// <example>logger.LogInformation("Processing request from {Address}", address)</example> |
| 73 | +public static void LogInformation(this ILogger logger, string? message, params object?[] args) |
| 74 | +``` |
| 75 | + |
| 76 | +请注意第三个参数 `message`, 但是注释中却是 `message template format`。所以我们的日志是应该这样 |
| 77 | + |
| 78 | +```chsarp |
| 79 | +logger.LogInformation("data: {Data}, {now}", Data, DateTime.Now); |
| 80 | +``` |
| 81 | + |
| 82 | +而不是这样 |
| 83 | + |
| 84 | +```csharp |
| 85 | +logger.LogInformation($"data: {Data}, {DateTime.Now}"); |
| 86 | +``` |
| 87 | + |
| 88 | +应为日志库是将模板缓存下来,而不是在输出的时候,就开始构造日志字符串。benchmark 测试 |
| 89 | + |
| 90 | +```csharp |
| 91 | +[MemoryDiagnoser] |
| 92 | +public class BenchmarkLogging |
| 93 | +{ |
| 94 | + public static readonly ILogger logger; |
| 95 | + |
| 96 | + public static readonly Random random; |
| 97 | + |
| 98 | + private int Data => random.Next(); |
| 99 | + |
| 100 | + static BenchmarkLogging() |
| 101 | + { |
| 102 | + logger = new LoggerFactory().CreateLogger<BenchmarkLogging>(); |
| 103 | + random = new Random(); |
| 104 | + } |
| 105 | + |
| 106 | + [Benchmark] |
| 107 | + public void Templated() |
| 108 | + { |
| 109 | + logger.LogInformation("data: {Data}, {now}", Data, DateTime.Now); |
| 110 | + } |
| 111 | + |
| 112 | + [Benchmark] |
| 113 | + public void Interpolated() |
| 114 | + { |
| 115 | + logger.LogInformation($"data: {Data}, {DateTime.Now}"); |
| 116 | + } |
| 117 | + |
| 118 | + [Benchmark] |
| 119 | + public void Formatted() |
| 120 | + { |
| 121 | + logger.LogInformation(string.Format("data: {0}, {1}", Data, DateTime.Now)); |
| 122 | + } |
| 123 | +} |
| 124 | +``` |
| 125 | + |
| 126 | + |
| 127 | + |
| 128 | +可以看出,模板方法在性能和内存方面都优势。 |
| 129 | + |
| 130 | +4、[.NET 云应用程序](https://www.infoq.com/presentations/net-apps-cloud/) |
| 131 | + |
| 132 | +[](https://www.infoq.com/presentations/net-apps-cloud/) |
| 133 | + |
| 134 | +最近 `InfoQ` 组织了一场讨论 `.NET` 和云应用迁移的讨论,主要包含下面主题 |
| 135 | + |
| 136 | +- `.NET` 开发者在面对云的主要痛点 |
| 137 | +- 最小的迁移成本 |
| 138 | +- 当迁移到云之后,下一步该怎么办 |
| 139 | +- 选择 `Serverless` 还是 `Kubernetes` |
| 140 | +- 托管容器平台 |
| 141 | +- 除了 `App Service` 还有其他最有选择 |
| 142 | +- .... |
| 143 | + |
| 144 | +## 开源项目 |
| 145 | + |
| 146 | +1、[Visual Studio 环绕选择](https://github.com/madskristensen/Surrounder) |
| 147 | + |
| 148 | + |
| 149 | + |
| 150 | +在编辑器中,我们常常需要一个功能就选择为一段文本或者代码添加双引号,括号等等。通常我们的操作是分别找到开始位置和结束位置,然后分别输入开始字符和结束字符。`Surrounder` 插件可以帮助我们方便的完成,只要选择该文件,然后输入开始字符,结束字符会自动开结尾添加上。 |
0 commit comments