2012-09-03 38 views
2

我知道在C#中,作爲混合語言,得到了操作符,它們不是對象,就像在smalltalk中一樣。把一個操作符當作對象

有沒有辦法將它們當作對象(如Smalltalk)? 我的意思是,給它們添加屬性和方法,或者將它們包含在類層次結構中。

據我所知,(感謝谷歌),有可能overload an operator,但我找不到其他東西。

例如,我想知道如果有可能的待辦事項像

if(+.PrecedenceLevel > *.PrecedenceLevel) 
{ 
//something 
} 

僅僅是一個我的好奇心的問題,不是我的工作。

+2

不,這是不可能的。 –

+0

你的意思是'公章類+ {...}'?那麼'1 + 2'會做什麼? – perilbrain

+0

正如我向Jon Skeet提到的那樣,假設我想這樣做(+。PrecedenceLevel> * .PrecedenceLevel){something} 但是你說得對,我沒有考慮1 + 2會做什麼。但我想這只是實施,對吧?我的意思是,在Smalltalk中,據我讀 –

回答

3

重載運算符是靜態方法,因此有相應的MethodInfo對象可以被操縱或調用:

var eqStr = typeof(string).GetMethod("op_Equality"); 
Console.WriteLine(eqStr.Name);//op_Equality - the .NET name rather than the C# name 
Console.WriteLine(eqStr.IsSpecialName);//True - languages may give it a different name 
Console.WriteLine(eqStr.Invoke(null, new object[]{"abc", "abc"}));//True 
Console.WriteLine(eqStr.Invoke(null, new object[]{"abc", "def"}));//False 

這真的只是讓我們在方法的語言無關的功能得到,雖然,這可能是但它不會讓我們知道給定語言使用的名稱(C#中的==,VB.NET中的=等),其優先級或任何「操作性」可以這麼說。

它只針對重載,而不是內建。

+2

我不知道.Net以這種方式對待操作員。很有意思 ! –

+2

@ElVieejo再次,但只有重載。不能以這種方式訪問​​'1 + 2'的'+',因爲它是用BCL語言定義的。同樣,雖然這告訴我們一種語言可能會給它一個「特殊名稱」,但它並沒有告訴我們C#有用,或者那個名字是'=='。 –

2

簡短的答案是「否」,運算符不是C#中的對象,甚至通過靜態方法的運算符重載機制似乎是一種弱設計,因此您很少看到C#運算符重載的性感示例。但是,如果你有好奇心,除了Jon已經提到的Reflection之外,.NET中還有更多的元編程機制,其中運算符由對象表示。你仍然無法給他們任何額外的屬性或檢查優先順序,但這可能是你在.NET中最接近你描述的東西。

一種方法是通過使用代碼DOM,有一個CodeBinaryOperationExpression類。當你閱讀或創建一個,你可以使用CodeBinaryOperatorType enum來指定運算符。例如,您可以在C#中創建一個方法,該方法將在運行時使用動態選擇的運算符創建表達式樹,將其編譯爲lambda表達式並傳遞給調用方以用作常用函數。

另一種與之前相反的方式是使用新的Roslyn API,它提供了代碼解析功能。您可以將一些源代碼提供給Roslyn,它會將它轉換爲表達式樹,並且您可以編寫visitors or syntax rewriters來修改該樹。例如,您可以通過樹並用「減號」運算符(或用您選擇的任何代碼)替換所有「加號」運算符。

你可以找到更多的細節和例子herehere

HTH。

+0

這很有意思。我聽說過表達樹,但從未使用過,我不知道如何使用它們。謝謝 ! +1 –