2009-08-09 58 views
13

由於C#運營商例如+,+ =,==是可覆蓋的。它讓我認爲他們是一種方法,因此想知道是否有方法使用反射來調用它們,例如在Int32上。是否可以通過反射調用值類型運算符?

+6

運算符不能*覆蓋*。他們可以*重載*。有很大的不同。 – 2009-08-09 15:11:56

+1

爲了更清楚起見,重寫允許您重新定義實現,重載允許您添加具有相同名稱但具有不同參數的另一個方法。謝謝你的評論。 – 2009-08-12 08:24:21

+0

回覆評論並添加了非打字的示例。 – 2009-08-12 08:27:25

回答

7

是的,自定義運算符可以使用反射來調用(它們有特殊的名稱,比如op_Addition),但System.Int32沒有定義它們,因爲基本的內置類型直接由IL操作碼處理,如add而不是方法調用。

+1

什麼是自定義演員操作符? – 2010-08-03 21:51:16

+1

回答自己的子問題 - 事實證明它們是「op_Implicit」和「op_Explicit」,可以有多個版本相同的名稱,只有返回類型不同。 – 2010-08-03 23:42:42

0

這將是非常低效的,如果相加或比較兩個整數需要一個方法調用等的基本類型的這些簡單的操作進行碼生成如在另一種答案說明,並且不能使用反射被調用。一個有趣的內置值類型是decimal(或System.Decimal)。此struct具有用於在C#文字值的支持,但表現很像真實值類型和暴露了很多,可以通過反射調用運營商。

如果你好奇,你可以使用Reflector瀏覽依System.Int32暴露的所有成員。

0

有很好的答案在這裏,所以我想補充一些尚未提到:

一個結構可能有一個operator overloaded。這意味着更多選項來檢查您是否嘗試創建一些程序化方法。

一個好處嘗試就是要嘗試表達式樹的方法。 Here是一個小樣本。當然,表現並不太好,但我們知道我們正在使用Reflection進行研究。

4

究竟什麼是你想要做什麼?處理操作符的各種含義(原語(映射到特定的IL指令),自定義(映射到靜態方法)和解除(由編譯器提供的模式))使得這種痛苦。如果你只是想使用運營商,則可以編寫代碼,提供了通過泛型運營商的支持。我有一些代碼可以在MiscUtildescription and examples)中免費獲得。


作爲非類型化的例子(注的,這不是巨大的效率,但工程):

object x = 123, y = 345; // now forget that we know that these are ints... 
object result = Expression.Lambda<Func<object>>(
    Expression.Convert(Expression.Add(
     Expression.Constant(x), Expression.Constant(y)), 
    typeof(object))).Compile()(); 
+0

其實我想實現一個添加(對象左,對象的權利),其中返回的值是使用左側參數的類型。這是用於表達式評估的,因爲它是動態的,所以沒有辦法直接編寫代碼。 – 2009-08-12 08:21:46

+1

在這種情況下,你會喜歡4.0中的「動態」 - 它會做的很多這個... – 2009-08-12 08:23:25

+0

必須不同意選擇4。0,因爲Seb的工作重點集中在一起,並且與表達式樹膨脹和發明相比,性能相當差。判斷DLR及其含有的位的性能只會使即將到來的PDC發佈人類歷史上最慢的框架。 – 2009-10-14 08:26:37

8

這個怎麼樣,它的簡單,體積小,工作:)

public T Add<T>(object x, object y) 
{ 
    return (T)Convert.ChangeType((dynamic)x + (dynamic)y, typeof(T)); 
} 
+0

這在我的應用程序中非常漂亮。第一次我真的使用「動態」。我喜歡! – Boinst 2013-06-21 05:19:29

相關問題