有没有一种简单的方法可以在 C# 中创建多行字符串文字?
这是我现在拥有的:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
我知道 PHP 有
<<<BLOCK
BLOCK;
C#有类似的东西吗?
42
绑定为参数,尤其是当它来自用户输入时,以避免 SQL 注入。
您可以在 string
前面使用 @
符号来形成 verbatim string literal:
string query = @"SELECT foo, bar
FROM table
WHERE id = 42";
当您使用此方法时,您也会 do not have to escape special characters,但 Jon Skeet 的答案中显示的双引号除外。
它在 C# 中称为 verbatim string literal,只需将 @ 放在文字前即可。这不仅允许多行,而且还关闭转义。因此,例如,您可以这样做:
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>";
$@"{{example literal text { fooString }. }}"
这可能会让一些人感到困惑,因为 Angular、React 和 Vue.js 使用相反的约定。
{date.ToString("yyyy-mm-dd")}
您可能需要考虑@dav_i 答案,因为插值更干净,而不必弄乱双引号
我发现使用字符串文字的问题是它会使您的代码看起来有点“奇怪”,因为为了不在字符串本身中出现空格,它必须完全左对齐:
var someString = @"The
quick
brown
fox...";
呸。
所以我喜欢使用的解决方案是:
var someString = String.Join(
Environment.NewLine,
"The",
"quick",
"brown",
"fox...");
当然,如果您只是想像现在这样在逻辑上拆分 SQL 语句的行并且实际上不需要新行,您总是可以将 Environment.NewLine
替换为 " "
。
"The", "Quick", $"{fox.color}", "Fox"
的事情
另一个需要注意的问题是在 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++ 中多行字符串文字中的尾部反斜杠一样。
建议使用逐字字符串,不要介意 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
)";
}
createTable("MyTable");
无论如何,OP 的问题是关于如何输入多行字符串文字直接在代码中,而不是如何构建数据库查询本身。 :)
是的,您可以将一个字符串拆分为多行,而无需在实际字符串中引入换行符,但它并不漂亮:
string s = $@"This string{
string.Empty} contains no newlines{
string.Empty} even though it is spread onto{
string.Empty} multiple lines.";
诀窍是引入评估为空的代码,并且该代码可能包含换行符而不影响输出。我将这种方法从 this answer 调整为类似的问题。
对于问题是什么,显然有些混淆,但有两个提示,我们在这里想要的是一个不包含任何换行符的字符串文字,其定义跨越多行。 (在他这么说的评论中,“这就是我所拥有的”显示了不会创建带有换行符的字符串的代码)
此单元测试显示了意图:
[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.
如果您愿意,可以运行上述 here。
在 C# 11 [2022] 中,您将能够使用原始字符串文字。使用原始字符串文字可以更轻松地使用 " 字符,而无需编写转义序列。
OP的解决方案:
string query1 = """
SELECT foo, bar
FROM table
WHERE id = 42
""";
string query2 = """
SELECT foo, bar
FROM table
WHERE id = 42
and name = 'zoo'
and type = 'oversized "jumbo" grand'
""";
有关原始字符串文字的更多详细信息
有关完整详细信息,请参阅 Raw String Literals GitHub 问题;和Blog article C# 11 Preview Updates – Raw string literals, UTF-8 and more!
不定期副业成功案例分享
@"my string".Replace(Environment.NewLine, "")