7

我开始学习 C#,但我不明白为什么常规字符串文字(即" ")不能包含文字换行符。(我不是在谈论转义序列\n)。我知道您必须@" "对多行字符串使用逐字字符串文字(即,),但为什么呢?

常规字符串产生 逐字字符串不会产生错误

我没有看到它明确指出您不能在常规字符串中使用它们。不仅如此,除了顺便提到我可以为此使用逐字字符串之外,我读过的所有内容似乎都表明在常规字符串文字中允许使用文字换行符。

开始 Visual C# 2010代码:生成多行字符串文字 (Visual C#)显示逐字多行字符串的示例,无需进一步解释。

学习 C# 3.0是这样说的:

在 C# 语言中,空格、制表符和换行符被认为是空格......在 C# 语句中通常会忽略额外的空格。...该规则的例外是字符串中的空格被视为文字;它没有被忽视。

所以是字面意思?这也是我所期望的,但事实并非如此。
它甚至包括这个提示框:

提示
Visual Basic 程序员注意:在 C# 中,行尾没有特殊意义。语句以分号结尾,而不是换行符。没有行继续字符,因为不需要。

(我意识到这是在谈论字符串之外,但是如果它不在字符串之外,为什么行尾在字符串内部具有特殊的解析意义?)

终于找到了字符串(C# 参考)本身的方法,我仍然没有获得任何见解:

字符串文字可以包含任何字符文字。包括转义序列。以下示例\\对反斜杠、\u0066字母 f 和\n换行符使用转义序列。

它说可以使用转义序列,但没有说必须使用它们。“任何字符文字”中是否不包含文字换行符?如果我有一个包含文字制表符而不是其转义序列的字符串,\t则没有错误。但是如果我有一个文字换行符,我会得到一个错误。我什至将文件的行尾从\r\nto更改\n\r无效。


显然,我可以从示例和 Visual Studio 错误中推断出,如果它包含文字换行符,则需要逐字字符串,但我读过的所有内容都表明不应该是这种情况。为什么有区别?

4

4 回答 4

5

嗯,开枪。就在我提交这个的时候,我找到了答案。

“任何字符文字”中是否不包含文字换行符?

显然,不,他们不是。

2.4.4.4 字符文字

字面量:

' 特点 '

特点:

单字

单字:

' (U+0027)、\ (U+005C) 和换行符之外的任何字符

于 2012-08-30T21:56:25.580 回答
1

为什么 C/C++ 字符串文字声明必须是单行的?

简而言之,因为C语言不支持它。

使字符串文字未闭合的拼写错误会将文件的其余部分作为单个标记吞下,给程序员留下一条编译器错误消息,类似于“在第 xxx 行,第 yyy 列期望分号”,其中指示的位置是源文件的结尾。

大多数情况下,您不使用多行文字。最好从用户体验的角度明确它们。

此外,在受限环境中,C 语言是在(8K PDP-11?)中开发的,我怀疑这种溢出可能会使编译器崩溃。

不过,C 语言确实支持文字拼接,这很有帮助:

char *txt = "this is line 1\n"
            "this is line 2\n"
            "this is line 3\n"
            ;

它还支持线拼接:

char *txt = "this is my\n\
 multi-line string literal\n\
 isn't it nice?\n" ;

我希望 C# 拥有的功能。

于 2012-08-30T22:08:40.977 回答
1

C#(以及影响其语法的 C++、C、Java)对空格有一个非常简单的规则:

你可以用它做你想做的事。

这可以让你使用任何你想要的格式来提高可读性。现在,Python 爱好者可能会说这个优势被高估了,但它是我们确实利用的优势。

字符串中的换行符可能会搞砸。如果您不确定源代码中的换行符是否应该意味着我们将"\u000D", "\u000A", "\u000A\u000D", "\u0085", "\u000B","\u000C"或换行的方式,其他人都错了”。"\u2028""\u2029"

你仍然可以争辩说,允许它的缺点被高估了。C# 确实如此——毕竟,与人们对 C++ 等的期望不同的字符串形式确实允许

于 2012-08-30T22:15:40.223 回答
0

看起来这个限制将在 C# 11 中删除。

C# 11 Preview: Allow newlines in the "holes" of interpolated strings

C# 支持两种类型的插值字符串:逐字和非逐字插值字符串(分别为$@""$"")。它们之间的一个关键区别是非逐字插值字符串不能在其文本段中包含换行符,而必须使用转义符(如\r\n)。逐字插值字符串可以在其文本段中包含换行符,并且不会转义换行符或其他字符(除了""转义引号本身)。所有这些行为保持不变。

以前,这些限制扩展到非逐字插值字符串的孔。孔是表示插值表达式的简写方式,是花括号内提供运行时值的部分。孔本身不是文本,不应遵守内插字符串文本段的转义/换行规则。

例如,以下内容会导致 C# 10中的编译器错误,并且在此C# 11预览版中是合法的:

var v = $"Count ist: { this.Is.Really.Something()
                            .That.I.Should(
                                be + able)[
                                    to.Wrap()] }.";

这是相关的 Github 问题:https ://github.com/dotnet/cshaplang/issues/4935

于 2022-02-27T19:10:56.073 回答