-2

如果我存储逐字字符串, string s=@""Hello"";它应该假设解析字符串并打印"Hello"(将"字符作为字符串的一部分)

但在实际实践中,它会失败,而是string s=@"""Hello""";显示所需的输出 ( "Hello")。

为什么语法需要一个额外的"字符?如果 C# 开始以上述假设的方式运行,将会产生什么破坏性结果?

4

2 回答 2

7

所以从技术上讲,字符串 s=@""Hello""; 应该打印“你好”

不,那将是无效的。编译器应该 - 并且确实 - 遵守语言规范的规则。

在逐字字符串文字中,双引号必须加倍(而不是三倍)以将它们与仅表示“字符串结尾”的双引号区分开来。

如果您在字符串中间使用双引号,而不是在开头或结尾处,则最容易看到这一点:

string x = @"start "" end";

F# 在上述情况下完美运行

据我所见。在 VS2015 Preview 的示例 F# 项目中:

let x = @""Hello""

... 给出一个错误,而@"""Hello"""导致一串"Hello".

此外,F# 逐字字符串文字文档表明它完全按照 C# 工作:

如果前面有 @ 符号,则文字是逐字字符串。这意味着任何转义序列都被忽略,除了两个引号字符被解释为一个引号字符

基本上,听起来逐字字符串文字在 C# 和 F# 中都可以很好地工作,它们都需要双引号。F# 也有三重引号的字符串,在其中它们不需要加倍......但这只是 C# 没有的一个单独的功能。

编辑:为了回答您关于歧义的评论,您举了一个@"1"2"". 让我稍微改变一下:

string x = @"1"+"";

目前在 C# 中,这意味着将逐字字符串文字与内容1和空的常规字符串文字连接起来。如果您建议它实际上应该是一个带有 content 的逐字字符串文字1"+",而解析器直接在下一个分号之前依赖引号作为逐字字符串文字的结尾,这让我觉得这是一个非常糟糕的主意。例如,假设我想在双参数方法调用中使用逐字字符串文字作为第一个参数,如下所示:

Console.WriteLine(@"Foo {0}", "Bar");

根据您的规则,这将是一个带有单个参数的调用 - 不可能将我们尝试进行的调用表示为单个语句。(您需要为逐字字符串文字使用变量以避免它搞砸。)

简而言之,我对 C# 已经工作的方式更满意。

于 2014-12-30T13:02:41.457 回答
2

那是因为你也需要有一个开头和结尾的 " 字符。所以像你这样的一行:

s=@"""Hello""";

第一个和最后一个引号字符是向编译器指示字符串的开始和结束。然后在字符串中,双引号序列 ("") 表示您希望在字符串中包含引号字符。

于 2014-12-30T13:02:47.937 回答