字符串插值中的 lambda 表达式
lambda expressions in string interpolation
我正在尝试在字符串插值中使用 lambda 表达式,方法是:
var sb = new StringBuilder();
var a = $@"test { () => {
var sb = new StringBuilder();
foreach (var v in new string[] { "abc", "def", "ghi" })
sb.Append(v);
return sb.ToString();
}} test";
var b = $@"test {F1()} test";
Console.WriteLine(a);
Console.WriteLine(b);
string F1()
{
var sb = new StringBuilder();
foreach (var v in new string[] { "abc", "def", "ghi" })
sb.Append(v);
return sb.ToString();
}
这给出了以下输出:
test System.Func`1[System.String] test
test abcdefghi test
实际用例更复杂:我有一个包含 html 格式的邮件正文的字符串,我需要在几个地方插入几行 table 行。
我认为在 lambda 表达式中放置 forach 循环是个好主意:我发现这样的结果非常易读。
不幸的是,我看到 c# 在表达式上调用 ToString(),而不是返回表达式值本身。
如果我调用外部函数,则不会发生这种情况。
I see that c# invokes ToString() on the expression
是的,因为它将委托视为对象,并且在理解如何处理对象方面缺少任何更具体的内容,所以它只是在其上调用 ToString()。
你的两次尝试之间有一个关键的区别,如果我把委托拉出来可能会更清楚:
var f = () => {
var sb = new StringBuilder();
foreach (var v in new string[] { "abc", "def", "ghi" })
sb.Append(v);
return sb.ToString();
};
var a = $@"test {f} test";
var b = $@"test {F1()} test";
var c = $@"test {f()} test";
F1
被调用是因为它由 ()
执行并且其返回结果包含在字符串中。 f
没有被调用,所以 f 本身是什么 成为包含在字符串中的东西
var c
版本如您所料工作..(在我看来,这是一种更简洁的结构方式;本地函数也可以清理它)
在这种特殊情况下,您可能还想考虑:
var d = $@"test {new[]{"abc","def","ghi"}.Concat()} test"
我正在尝试在字符串插值中使用 lambda 表达式,方法是:
var sb = new StringBuilder();
var a = $@"test { () => {
var sb = new StringBuilder();
foreach (var v in new string[] { "abc", "def", "ghi" })
sb.Append(v);
return sb.ToString();
}} test";
var b = $@"test {F1()} test";
Console.WriteLine(a);
Console.WriteLine(b);
string F1()
{
var sb = new StringBuilder();
foreach (var v in new string[] { "abc", "def", "ghi" })
sb.Append(v);
return sb.ToString();
}
这给出了以下输出:
test System.Func`1[System.String] test
test abcdefghi test
实际用例更复杂:我有一个包含 html 格式的邮件正文的字符串,我需要在几个地方插入几行 table 行。 我认为在 lambda 表达式中放置 forach 循环是个好主意:我发现这样的结果非常易读。
不幸的是,我看到 c# 在表达式上调用 ToString(),而不是返回表达式值本身。
如果我调用外部函数,则不会发生这种情况。
I see that c# invokes ToString() on the expression
是的,因为它将委托视为对象,并且在理解如何处理对象方面缺少任何更具体的内容,所以它只是在其上调用 ToString()。
你的两次尝试之间有一个关键的区别,如果我把委托拉出来可能会更清楚:
var f = () => {
var sb = new StringBuilder();
foreach (var v in new string[] { "abc", "def", "ghi" })
sb.Append(v);
return sb.ToString();
};
var a = $@"test {f} test";
var b = $@"test {F1()} test";
var c = $@"test {f()} test";
F1
被调用是因为它由 ()
执行并且其返回结果包含在字符串中。 f
没有被调用,所以 f 本身是什么 成为包含在字符串中的东西
var c
版本如您所料工作..(在我看来,这是一种更简洁的结构方式;本地函数也可以清理它)
在这种特殊情况下,您可能还想考虑:
var d = $@"test {new[]{"abc","def","ghi"}.Concat()} test"