消息模板应该是编译时常量

Ali*_*Ali 20 c# .net-core rider

我有这个代码

[HttpGet("average/{videoGuid}")]
public async Task<IActionResult> AverageRatingOfVideo([FromRoute] string videoGuid)
{
    _logger.LogInformation($"Finding average rating of video : {videoGuid}");
    var avg = await _ratingService.GetVideoRatingAverageAsync(videoGuid);
    return Ok(avg);
}
Run Code Online (Sandbox Code Playgroud)

我在这里收到警告 $"Finding average rating of video : {videoGuid}"

消息模板应该是编译时常量

我正在使用Rider,没有修复此警告的建议。

我不明白为什么这会给我一个警告,我该如何解决?

Rol*_*lin 30

摆脱警告的方法是单独提供变量 videoGuid,如下所示:

_logger.LogInformation("Finding average rating of video : {VideoGuid}", videoGuid);
Run Code Online (Sandbox Code Playgroud)

在这里,我首先删除了 $ 符号,从而关闭了 C# 执行的字符串插值。的{videoGuid}字符串中现在变成了“属性”代替,所以我通过该变量作为第二个参数LogInformation。Rider 还抱怨字符串中的属性应该以大写字母开头,因此我将其更改为{VideoGuid}.

现在真正的问题是:为什么会有警告?

答案是字符串插值会阻止结构化日志记录。当您在消息之后传递变量时,您可以让记录器单独保存它们。如果您只是将日志保存到文件中,您可能看不到任何区别,但是如果您稍后决定将日志记录到数据库或以某种 JSON 格式,您只需更改您的日志记录接收器,您就可以在日志中进行大量搜索在不更改代码中的所有日志语句的情况下更容易。

Software Engineering Stack Exchange上有一个很好的讨论。

  • 对我来说,解决方案(Rider/MS/C# 创建者提供的?)没有意义,它可能会误导代码,因为命名参数只是有序参数 - 没有名称匹配,因此代码 `logger.LogDebug("hey {Foo} , hi {Bar}", bar, foo);` 将记录 `hey bar, hi foo`,甚至重命名变量 `bar` 和 `foo` 会使代码变得奇怪 `...("hey {Foo}, hi {Bar}", big, bang);` - Rider/ReSharper 不支持在 {} 中重命名以及 atm。 (11认同)
  • @svonidze 如果您是库开发人员,那么不要忽略此警告,这一点绝对至关重要,因为您将用无法正确删除或压缩的消息淹没下游日志记录系统。在这种情况下,是否“更干净”并不重要,因为在使用结构化日志记录框架时,非常量模板是错误的。 (6认同)
  • @thargenediad https://www.merriam-webster.com/dictionary/elide (3认同)