有没有一种简单的方法可以在 C# 中创建多行字符串文字?
这是我现在拥有的:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
我知道 PHP 有
<<<BLOCK
BLOCK;
C#有类似的东西吗?
它在 C# 中称为逐字字符串文字,只需将 @ 放在文字之前即可。这不仅允许多行,而且还关闭转义。因此,例如,您可以这样做:
string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";
但是,这包括在字符串中的换行符(使用您的源代码中的任何换行符)。对于 SQL,这不仅是无害的,而且可能会提高您在任何地方看到字符串的可读性 - 但在其他地方可能不需要它,在这种情况下,您要么不需要使用多行逐字字符串文字开始,或从结果字符串中删除它们。
唯一的转义是如果你想要一个双引号,你必须添加一个额外的双引号符号:
string quote = @"Jon said, ""This will work,"" - and it did!";
附带说明一下,在 C# 6.0 中,您现在可以将内插字符串与逐字字符串文字结合起来:
string camlCondition = $@"
<Where>
<Contains>
<FieldRef Name='Resource'/>
<Value Type='Text'>{(string)parameter}</Value>
</Contains>
</Where>";
我发现使用字符串文字的问题是它会使您的代码看起来有点“奇怪”,因为为了不在字符串本身中出现空格,它必须完全左对齐:
var someString = @"The
quick
brown
fox...";
呸。
所以我喜欢使用的解决方案是:
var someString = String.Join(
Environment.NewLine,
"The",
"quick",
"brown",
"fox...");
当然,如果您只是想像现在这样在逻辑上拆分 SQL 语句的行并且实际上不需要新行,您总是可以替换Environment.NewLine
为" "
.
另一个需要注意的问题是在 string.Format 中使用字符串文字。在这种情况下,您需要转义花括号/括号“{”和“}”。
// this would give a format exception
string.Format(@"<script> function test(x)
{ return x * {0} } </script>", aMagicValue)
// this contrived example would work
string.Format(@"<script> function test(x)
{{ return x * {0} }} </script>", aMagicValue)
为什么人们总是将字符串与字符串文字混淆?接受的答案是对不同问题的一个很好的答案;不是这个。
我知道这是一个老话题,但我来到这里可能与 OP 相同的问题,看到人们如何继续误读它令人沮丧。或者我看错了,我不知道。
粗略地说,字符串是计算机内存的一个区域,在程序执行期间,它包含可以映射到文本字符的字节序列。另一方面,字符串字面量是一段尚未编译的源代码,它表示稍后在其出现的程序执行期间用于初始化字符串的值。
在 C# 中,语句...
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
...不产生三行字符串,而是产生单行;三个字符串的串联(每个都从不同的文字初始化),其中没有一个包含换行符。
OP 似乎在问什么——至少我会用这些话问什么——不是如何在编译的字符串中引入模仿源代码中的换行符,而是如何长时间分解以保持清晰, 源代码中的单行文本,而不会在编译的字符串中引入中断。并且不需要延长执行时间,就可以将来自源代码的多个子字符串连接起来。就像 javascript 或 C++ 中多行字符串文字中的尾部反斜杠一样。
建议使用逐字字符串、nevermind StringBuilder
s、String.Join
s 甚至是带有字符串反转的嵌套函数等等,这让我觉得人们并没有真正理解这个问题。或者也许我不明白。
据我所知,C# 没有(至少在我仍在使用的旧石器时代版本中,从前十年开始)具有干净地生成多行字符串文字的功能,这些文字可以在编译期间而不是执行期间解决。
也许当前版本确实支持它,但我想我会分享我在字符串和字符串文字之间感知的差异。
更新:
(来自 MeowCat2012 的评论)你可以。OP 的“+”方法是最好的。根据规范保证优化:http ://stackoverflow.com/a/288802/9399618
添加多行:使用@
string query = @"SELECT foo, bar
FROM table
WHERE id = 42";
将字符串值添加到中间:使用 $
string text ="beer";
string query = $"SELECT foo {text} bar ";
多行字符串向中间添加值:使用 $@
string text ="Customer";
string query = $@"SELECT foo, bar
FROM {text}Table
WHERE id = 42";
您可以使用@和""。
string sourse = @"{
""items"":[
{
""itemId"":0,
""name"":""item0""
},
{
""itemId"":1,
""name"":""item1""
}
]
}";
我还没有看到这个,所以我会把它贴在这里(如果你有兴趣传递一个字符串,你也可以这样做。)这个想法是你可以将字符串分成多行并添加你自己的内容(也在多行上)以您希望的任何方式。这里“tableName”可以传入字符串。
private string createTableQuery = "";
void createTable(string tableName)
{
createTableQuery = @"CREATE TABLE IF NOT EXISTS
["+ tableName + @"] (
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Key] NVARCHAR(2048) NULL,
[Value] VARCHAR(2048) NULL
)";
}
是的,您可以将一个字符串拆分为多行,而无需在实际字符串中引入换行符,但它并不漂亮:
string s = $@"This string{
string.Empty} contains no newlines{
string.Empty} even though it is spread onto{
string.Empty} multiple lines.";
诀窍是引入评估为空的代码,并且该代码可能包含换行符而不影响输出。我将这种方法从这个答案改编为类似的问题。
对于问题是什么,显然有些混淆,但有两个提示,我们在这里想要的是一个不包含任何换行符的字符串文字,其定义跨越多行。(在他这么说的评论中,“这就是我所拥有的”显示了不会创建带有换行符的字符串的代码)
此单元测试显示了意图:
[TestMethod]
public void StringLiteralDoesNotContainSpaces()
{
string query = "hi"
+ "there";
Assert.AreEqual("hithere", query);
}
更改上述查询的定义,使其成为一个字符串文字,而不是两个字符串文字的串联,编译器可能会或可能不会优化为一个字符串文字。
C++ 方法是用反斜杠结束每一行,导致换行符被转义并且不会出现在输出中。不幸的是,仍然存在这样的问题,即第一行之后的每一行都必须左对齐,以免在结果中添加额外的空格。
只有一个选项不依赖于可能不会发生的编译器优化,那就是将您的定义放在一行上。如果你想依赖编译器优化,你已经拥有的 + 很棒;你不必左对齐字符串,你不会在结果中得到换行符,而且它只是一个操作,没有函数调用,可以期待优化。
如果您不想要空格/换行符,则字符串添加似乎有效:
var myString = String.Format(
"hello " +
"world" +
" i am {0}" +
" and I like {1}.",
animalType,
animalPreferenceType
);
// hello world i am a pony and I like other ponies.
如果您愿意,可以在此处运行上述代码。