如何在不进行系统调用的情况下获得恒定的字符串长度?

How to get the constant string length without making a system call?

示例代码:

const string UtcTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
public byte[] UtcTimeAscii => Encoding.ASCII.GetBytes(DateTime.UtcNow.ToString(UtcTimeFormat));

这是我为 Length 属性 得到的 IL:(使用 Microscope VS 添加)

现在:为什么有系统调用而不是普通的 24? 它是一个常量字符串。有没有办法提前告诉编译器它是已知的?

我知道,我可以将 24 定义为 const int,但这是不对的,因为实际字符串与其长度之间没有直接绑定。当然我可以调用 Length() 但我只是好奇,也许有特殊的语法来使用这种优化?

我也将配置从 Debug 切换到 Release 但系统调用仍然存在。

该优化(如果要完成的话)不会由 C# 编译器完成,而是由 JIT 编译器在(好吧,就在之前)运行时间完成。 IL 通常不指示正在发生的优化,并且永远不能证明不存在给定的优化。

因此,让我们看一下实际 运行 生成的机器代码。您可以在调试器中执行此操作,如果您关闭“禁用模块加载优化”(否则您会看到有意未优化的机器代码),或者您可以使用 sharplab.io: like this

C.M()
    L0000: mov eax, 0x18
    L0005: ret

结果很明显:获取常量字符串的长度优化为常量长度,不涉及调用甚至加载。顺便说一句,在任何情况下都不会是 system 调用,它可能是对子例程的正常调用。