2011-08-11 10 views
12

Gdy próbuje uruchomić następujący kod:"Operator binarny Add nie jest zdefiniowany dla typów" System.String "i" System.String "." - Naprawdę?

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

pojawia się błąd wymieniony w tytule: „Operator binarny dodawania nie jest zdefiniowana dla«System.String»typów i«System.String»” Czy tak jest naprawdę? Oczywiście w C# działa. Czy robisz string s = "A" + "B" w C# specjalnego cukru syntaktycznego, do którego kompilator wyrażeń nie ma dostępu?

+0

Followup Chyba: Dlaczego nie kompilator wyrażenie zrobić tę samą magię jako kompilatora C# ? – Shlomo

+0

Aby odpowiedzieć na pytanie, dlaczego tak się dzieje? Chociaż istnieją języki, które używają '+' jako operatora konkatenacji, a także operatora dodawania na typach liczbowych, to nie jest uniwersalne (innymi typowymi operatorami konkatencji są '.',' || ',' & ', << '), a nawet te, które używają' + 'nazywają to * konkatenacją * w tym kontekście. Metoda "Expression.Add" nazywa się 'Add' i można się spodziewać, że zrobi addycję i nie zrobi nic innego (chyba że typ przeciążył' + ', ale wtedy wewnętrznie jest to metoda o nazwie' op_addition', której typ pobiera to jest * dodaj *). –

Odpowiedz

12

To prawda, tak. Nie ma takiego operatora - kompilator C# konwertuje string + string na wywołanie string.Concat. (Jest to istotne, gdyż oznacza to, że x + y + z można przekształcić string.Concat(x, y, z) unikał tworząc łańcuchy pośrednich bezużytecznie

Zobacz na dokumentację by string operators -.. Tylko == i != są określone przez strukturę

4

Tak , to niespodzianka prawda !!! kompilator zastępuje go wezwanie do String.Concat.

4

to właśnie złapał mnie też, i jak Jon wskazuje w swej odpowiedzi, C# kompilator zamienia string + string w string.Concat. Istnieje overload of the Expression.Add method, który pozwala określić metodę "dodaj" do użycia.

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

Możesz chcieć zmienić metodę string.Concat korzystania z poprawną overload.

Udowodnienie to działa:

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

wyświetli:

hello world

Powiązane problemy