尝试运行以下代码时:
Expression<Func<string, string>> stringExpression = Expression.Lambda<Func<string, string>>(
Expression.Add(
stringParam,
Expression.Constant("A")
),
new List<ParameterExpression>() { stringParam }
);
string AB = stringExpression.Compile()("B");
我得到标题中引用的错误:“没有为类型'System.String'和'System.String'定义二进制运算符Add。”那是真的吗?显然在C#中它起作用。是否在表达式编译器无法访问的C#特殊语法糖中执行string s = "A" + "B"
?
答案 0 :(得分:12)
这是绝对正确的,是的。没有这样的运算符--C#编译器将string + string
转换为对string.Concat
的调用。 (这很重要,因为这意味着x + y + z
可以转换为string.Concat(x, y, z)
,这可以避免无意义地创建中间字符串。
查看string operators的文档 - 框架只定义==
和!=
。
答案 1 :(得分:4)
是的,这是一个惊喜不是它!编译器将其替换为对 String.Concat 的调用。
答案 2 :(得分:4)
这也引起了我的注意,正如Jon在答案中指出的那样,C#编译器会将string + string
转换为string.Concat
。有overload of the Expression.Add method允许您指定要使用的“添加”方法。
var concatMethod = typeof(string).GetMethod("Concat", new[] { typeof(string), typeof(string) });
var addExpr = Expression.Add(Expression.Constant("hello "),Expression.Constant("world"), concatMethod);
您可能希望更改string.Concat
方法以使用正确的overload。
证明这是有效的:
Console.WriteLine(Expression.Lambda<Func<string>>(addExpr).Compile()());
将输出:
你好世界