有没有一种简单的方法可以在C#中创建多行字符串文字?
这是我现在所拥有的:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
我知道PHP有
<<<BLOCK
BLOCK;
C#是否有类似的东西?
42
作为参数,特别是如果它来自用户输入,则应避免将其作为SQL注入。
有没有一种简单的方法可以在C#中创建多行字符串文字?
这是我现在所拥有的:
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
我知道PHP有
<<<BLOCK
BLOCK;
C#是否有类似的东西?
42
作为参数,特别是如果它来自用户输入,则应避免将其作为SQL注入。
Answers:
您可以使用@
a前面的符号string
形成逐字字符串文字:
string query = @"SELECT foo, bar
FROM table
WHERE id = 42";
使用此方法时,除了双引号(如Jon Skeet的答案所示)外,您也不必转义特殊字符。
@"my string".Replace(Environment.NewLine, "")
它在C#中称为逐字字符串文字,只是在文字之前加上@即可。这不仅允许多行,而且还关闭转义。因此,例如,您可以执行以下操作:
string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";
但是,这包括换行符(使用您的源使用的任何换行符)到字符串中。对于SQL来说,这不仅无害,而且可能会在您看到字符串的任何地方提高可读性-但在其他地方,则可能不需要这样做,在这种情况下,您无需使用多行逐字字符串字面量,或从结果字符串中删除它们。
转义的唯一点是,如果要双引号,则必须添加一个额外的双引号:
string quote = @"Jon said, ""This will work,"" - and it did!";
我发现使用字符串文字的问题在于,它会使您的代码看起来有些“ 怪异 ”,因为为了不在字符串本身中获得空格,必须将其完全左对齐:
var someString = @"The
quick
brown
fox...";
uck
因此,我喜欢使用的解决方案使所有内容与其余代码保持一致:
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)
附带说明,在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使用相反的约定。
人们为什么总是将字符串与字符串文字混淆?公认的答案是对其他问题的很好答案。不是这个。
我知道这是一个古老的话题,但是我来到这里时可能遇到与OP相同的问题,看到人们如何继续误读它令人沮丧。也许我读错了,我不知道。
粗略地说,字符串是计算机内存的区域,在程序执行期间,该字符串包含可映射为文本字符的字节序列。另一方面,字符串文字是一段尚未编译的源代码,它表示以后执行该字符串的程序执行期间用于初始化字符串的值。
在C#中,该语句...
string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";
... 不会产生三行线,而是产生一根线;三个字符串的串联(每个字符串都从不同的文字初始化),其中三个都不包含换行符。
OP似乎要问的问题-至少我要用这些词问的问题-不是如何在已编译的字符串中引入模仿源代码中所出现的换行符的方式,而是如何为清晰起见而长期分拆,即源代码中的单行文本,而不会在已编译的字符串中引入中断。而且不需要延长执行时间,就可以花一些时间来连接源代码中的多个子字符串。就像javascript或C ++中多行字符串文字中的尾部反斜杠一样。
建议使用逐字字符串,nevermind StringBuilder
,String.Join
s甚至是带有字符串反转的嵌套函数,而不要使用什么,使我认为人们并没有真正理解这个问题。也许我听不懂。
据我所知,C#(至少在我使用的旧石器版本中,至少在过去的十年中)没有干净地产生多行字符串文字的功能,这些文字可以在编译而不是执行期间进行解析。
也许当前的版本确实支持它,但是我想我应该分享我认为字符串和字符串文字之间的区别。
更新:
(来自MeowCat2012的评论)可以。OP的“ +”方法是最好的。根据规范,可以保证优化:http : //stackoverflow.com/a/288802/9399618
我还没有看到它,所以我将其张贴在这里(如果您有兴趣传递字符串,您也可以这样做。)这个想法是您可以将字符串分解成多行并添加自己的内容(也多行)以您希望的任何方式。在这里,“ 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.";
技巧是引入评估结果为空的代码,并且该代码可以包含换行符而不影响输出。我将这种方法从这个答案改编成一个类似的问题。
关于这个问题,显然有一些困惑,但是有两个提示,我们在这里想要的是不包含任何换行符的字符串文字,其定义跨越多行。(在他这样说的评论中,“这就是我所拥有的”显示的代码不会创建包含换行符的字符串)
此单元测试显示了意图:
[TestMethod]
public void StringLiteralDoesNotContainSpaces()
{
string query = "hi"
+ "there";
Assert.AreEqual("hithere", query);
}
更改查询的上述定义,以使其为一个字符串文字,而不是由编译器优化或不优化为两个字符串文字的串联。
C ++的方法是在每行以反斜杠结束,从而导致换行符被转义而不出现在输出中。不幸的是,仍然存在一个问题,即第一行之后的每一行都必须保持对齐,以便不向结果中添加额外的空格。
只有一个选项不依赖可能不会发生的编译器优化,这就是将您的定义放在一行上。如果您想依靠编译器优化,那么您已经拥有的+非常好;您不必将字符串左对齐,也不必在结果中得到换行符,而这只是一项操作,无需函数调用,就可以期待优化。
添加多行:使用@
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";
如果您不希望使用空格/换行符,则添加字符串似乎可以:
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.
如果愿意,可以在此处运行以上命令。
我知道我参加聚会有点晚了,但我想向这个线程的未来读者推荐https://www.buildmystring.com/。您可以使用此站点将任何代码转换为C#字符串文字。
您可以使用以下两种方法:
private static String ReverseString(String str)
{
int word_length = 0;
String result = "";
for (int i = 0; i < str.Length; i++)
{
if (str[i] == ' ')
{
result = " " + result;
word_length = 0;
}
else
{
result = result.Insert(word_length, str[i].ToString());
word_length++;
}
}
return result;
}
//NASSIM LOUCHANI
public static string SplitLineToMultiline(string input, int rowLength)
{
StringBuilder result = new StringBuilder();
StringBuilder line = new StringBuilder();
Stack<string> stack = new Stack<string>(ReverseString(input).Split(' '));
while (stack.Count > 0)
{
var word = stack.Pop();
if (word.Length > rowLength)
{
string head = word.Substring(0, rowLength);
string tail = word.Substring(rowLength);
word = head;
stack.Push(tail);
}
if (line.Length + word.Length > rowLength)
{
result.AppendLine(line.ToString());
line.Clear();
}
line.Append(word + " ");
}
result.Append(line);
return result.ToString();
}
在SplitLineToMultiline()中,您需要定义要使用的字符串和行长,这非常简单。谢谢 。