"El operador binario Add no está definido para los tipos 'System.String' y 'System.String'". -- ¿De Verdad?

c# expression-trees

Pregunta

Al intentar ejecutar el siguiente código:

    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");

Recibo el error al que se hace referencia en el título: "El operador binario Agregar no está definido para los tipos 'System.String' y 'System.String'". ¿Es realmente el caso? Obviamente en C # funciona. ¿Hacer la string s = "A" + "B" en el azúcar sintáctico especial de C # al que el compilador de expresiones no tiene acceso?

Respuesta aceptada

Es absolutamente correcto, sí. No existe tal operador: el compilador de C # convierte string + string en una llamada a string.Concat . (Esto es importante, porque significa que x + y + z se pueden convertir en string.Concat(x, y, z) que evita la creación de cadenas intermedias sin sentido.

Eche un vistazo a los documentos para operadores de cadena : solo == y != Están definidos por el marco.


Respuesta popular

Esto también me llamó la atención, y como Jon señala en su respuesta, el compilador de C # convierte string + string en string.Concat . Existe una sobrecarga del método Expression.Add que le permite especificar el método "agregar" para usar.

var concatMethod = typeof(string).GetMethod("Concat", new[] { typeof(string), typeof(string) }); 
var addExpr = Expression.Add(Expression.Constant("hello "),Expression.Constant("world"), concatMethod);

Es posible que desee cambiar el método string.Concat para utilizar la sobrecarga correcta.

Demostrando que esto funciona:

Console.WriteLine(Expression.Lambda<Func<string>>(addExpr).Compile()());

Saldrá:

Hola Mundo



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow