我想弄清楚为什么我的单元测试失败(下面的第三个断言):
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/