2011-08-11 22 views
12

Al intentar ejecutar el siguiente código:"El operador binario Add no está definido para los tipos 'System.String' y 'System.String'." -- ¿De Verdad?

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

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

+0

Seguimiento supongo: ¿Por qué no el compilador expresión hacer la misma magia como el compilador de C# ? – Shlomo

+0

Para responder al seguimiento, ¿por qué debería hacerlo? Si bien hay idiomas que usan '+' como un operador de concatenación, así como un operador de suma en los tipos numéricos, eso no es universal (otros operadores comunes de concat incluyen '.',' || ',' & ',' << ') e incluso aquellos que sí usan' + 'lo llaman * concatenación * en ese contexto. El método 'Expression.Add' se llama' Add' y se puede esperar que haga una adición y no haga nada más (a menos que un tipo tenga '' sobrecargado) pero dado que internamente se trata de un método llamado 'op_addition', el tipo está reclamando es un * add *). –

Respuesta

12

Está en lo cierto, sí. No existe tal operador: el compilador de C# convierte string + string en una llamada al string.Concat. (Esto es importante, porque significa que x + y + z se puede convertir en string.Concat(x, y, z) lo que evita la creación de cadenas intermedias sin sentido

Tener un vistazo a la documentación para string operators -.. Sólo == y != están definidos por el marco

4

Sí , que es una sorpresa no es que !!! el compilador reemplaza con una llamada a String.Concat.

4

Esto sólo me tomó demasiado, y como señala Jon en su respuesta, el compilador de C# convierte string + string en string.Concat. Hay un overload of the Expression.Add method 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 de string.Concat utilizar la correcta overload.

Demostrando que esto funciona:

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

seria:

hola mundo

Cuestiones relacionadas