c# - 字符串插值问题

标签 c# c#-6.0 string-interpolation

我想弄清楚为什么我的单元测试失败(下面的第三个断言):

var date = new DateTime(2017, 1, 1, 1, 0, 0);

var formatted = "{countdown|" + date.ToString("o") + "}";

//Works
Assert.AreEqual(date.ToString("o"), $"{date:o}");
//Works
Assert.AreEqual(formatted, $"{{countdown|{date.ToString("o")}}}");
//This one fails
Assert.AreEqual(formatted, $"{{countdown|{date:o}}}");

AFAIK,这应该可以正常工作,但它似乎没有正确传递格式化参数,它看起来只是代码的 {countdown|o}。知道为什么会失败吗?

最佳答案

这条线的问题

Assert.AreEqual(formatted, $"{{countdown|{date:o}}}");

是在要转义的变量的 format string 之后有 3 个弯引号,它开始从左到右转义,因此它将前 2 个弯引号视为 的一部分格式字符串和第三个大引号作为结束引号。

因此它将 o 转换为 o} 并且无法对其进行插值。

这应该可行

Assert.AreEqual(formatted, $"{{countdown|{date:o}"+"}");

请注意,更简单的 $"{date}}}"(即在变量后 没有 格式字符串的 3 个 curl )确实有效因为它认识到第一个大引号是结束引号,而 : 之后的格式说明符的解释破坏了正确的结束括号标识。

要证明格式字符串像字符串一样被转义,请考虑以下

$"{date:\x6f}"

被视为

$"{date:o}"

最后,双重转义弯引号完全有可能是自定义日期格式的一部分,因此编译器的行为是绝对合理的。再说一个具体的例子

$"{date:MMM}}dd}}yyy}" // it's a valid feb}09}2017

解析是一个基于表达式语法规则的形式化过程,不是看一眼就能搞定的。

关于c# - 字符串插值问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42142003/

相关文章:

c# - 现有 Canvas 中的 ItemsControl

c# - Unity AdMob 广告未显示

c# - 在 app.config 之外的 Entity Framework 中为 PostgreSQL 数据库设置一个 connectionString

c# - 为什么集合初始值设定项不能与表达式主体属性一起使用?

c# - 为什么 Json.NET 试图反序列化我的 get only 属性?

msbuild - 在 C# 6.0 代码库的 psake 构建中强制使用 MSBuild 14.0

c#-6.0 - 为什么在C#6中删除声明表达式?

powershell - 在命令中使用变量 (PowerShell)

kotlin - println() 产生不同的输出

ruby - 别名方法会导致不同的对象?