“没有为类型'System.String'和'System.String'定义二进制运算符Add。” - 真的吗?

时间:2011-08-11 14:10:00

标签: c# expression-trees

尝试运行以下代码时:

    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"

3 个答案:

答案 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()());

将输出:

  

你好世界