Durante il tentativo di eseguire il seguente codice:
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");
Ricevo l'errore di riferimento nel titolo: "L'operatore binario Aggiungi non è definito per i tipi 'System.String' e 'System.String'." È davvero così? Ovviamente in C # funziona. Sta facendo string s = "A" + "B"
nello speciale zucchero sintattico C # a cui il compilatore di espressioni non ha accesso?
È assolutamente giusto, sì. Non esiste un operatore di questo tipo: il compilatore C # converte string + string
in una chiamata a string.Concat
. (Questo è importante, perché significa che x + y + z
può essere convertito in string.Concat(x, y, z)
che evita di creare stringhe intermedie inutilmente.
Dai un'occhiata ai documenti per gli operatori di stringhe : solo ==
e !=
Sono definiti dal framework.
Anche questo mi ha sorpreso e, come sottolinea Jon nella sua risposta, il compilatore C # converte string + string
in string.Concat
. Si è verificato un sovraccarico del metodo Expression.Add che consente di specificare il metodo "add" da utilizzare.
var concatMethod = typeof(string).GetMethod("Concat", new[] { typeof(string), typeof(string) });
var addExpr = Expression.Add(Expression.Constant("hello "),Expression.Constant("world"), concatMethod);
È possibile che si desideri modificare il metodo string.Concat
per utilizzare il sovraccarico corretto.
Dimostrando che funziona:
Console.WriteLine(Expression.Lambda<Func<string>>(addExpr).Compile()());
Uscita:
Ciao mondo