2011-08-11 39 views
12

當試圖運行下面的代碼:「二元運算符Add沒有爲'System.String'和'System.String'類型定義。」 - 真的嗎?

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’。」這是真的嗎?很明顯,在C#中它起作用。在C#中做表達式編譯器無法訪問的特殊語法糖中的string s = "A" + "B"

+0

跟進我想:爲什麼不表達編譯器做同樣的魔法爲C#編譯器? – Shlomo

+0

要回答後續,爲什麼要這樣做?雖然有些語言使用'+'作爲連接運算符,並且在數字類型上使用加法運算符,但這不是通用的(其他常見的concat運算符包括'.','||','&','<< '),甚至那些在這種情況下使用'+'調用它* concatenation *的。 'Expression.Add'方法被稱爲'Add',人們可以期望它做另外的事情,而不是做任何其他的事情(除非一個類型重載了'+',但是因爲這在內部是一個名爲'op_addition'的方法,它是一個*添加*)。 –

回答

12

這是絕對正確的,是的。沒有這樣的操作符--C#編譯器將string + string轉換爲string.Concat的調用。 (這是重要的,因爲這意味着x + y + z可轉化成string.Concat(x, y, z)這避免無意義地創建中間串

看一看該文檔爲string operators - 。僅==!=由框架限定

4

呀,這是一個驚喜是不是!!!編譯器通過調用替換它String.Concat

4

這剛好趕上我出去過,和喬恩在他的回答中指出,C#編譯器轉換string + stringstring.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()()); 

將輸出:

的hello world

相關問題