2012-09-03 37 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 –