将运算符视为对象

时间:2012-09-03 16:22:28

标签: c# oop object operators

我知道在C#中,作为混合语言,得到了运算符,它们不是对象,就像在smalltalk中一样。

有没有办法将它们视为对象(如Smalltalk)? 我的意思是,向它们添加属性和方法,或将它们包含在类层次结构中。

据我所知,(感谢Google),我可以overload an operator,但我无法找到其他任何内容。

例如,我想知道它是否可能像

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

只是我的好奇心问题,而不是我的工作。

2 个答案:

答案 0 :(得分: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等中=,它的优先级或任何“操作性”可以这么说。

它只适用于重载,而不是内置插件。

答案 1 :(得分:2)

简短的回答是“不”,运算符不是C#中的对象,甚至通过静态方法的运算符重载机制似乎都是一种弱设计,所以你很少看到C#运算符重载的性感例子。 p>

但是,如果你是古玩,除了Jon已经提到的Reflection之外,.NET中还有一些元编程机制,其中运算符由对象表示。您仍然无法为其提供任何其他属性或检查优先级,但这可能是您在.NET中最接近您所描述的内容。

一种方法是使用Code DOM,有一个CodeBinaryOperationExpression类。当您阅读或创建一个时,使用CodeBinaryOperatorType枚举指定运算符。例如,您可以在C#中创建一个方法,该方法将在运行时创建一个带有动态选择的运算符的表达式树,将其编译为lambda并传回给调用者以用作公共函数。

另一种方式,与某种意义上的前一种方式相反,是使用新的Roslyn API,它提供了代码解析功能。您可以向Roslyn提供一些源代码,它会将其转换为表达式树,您可以编写visitors or syntax rewriters来修改该树。例如,您可以遍历树并使用“减号”运算符(或使用您选择的任何代码)替换所有“加”运算符。

您可以找到更多详细信息和示例herehere

HTH。