2

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

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

据我所知,(感谢谷歌),有可能重载 operator,但我找不到其他任何东西。

例如,我想知道是否可以做类似的事情

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

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

4

2 回答 2

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 等中),可以说它的优先级或任何“操作性”。

而且它仅适用于重载,而不适用于内置插件。

于 2012-09-03T16:41:04.367 回答
2

简短的回答是“不”,运算符不是 C# 中的对象,甚至通过静态方法的运算符重载机制似乎也是一种弱设计,因此您很少看到 C# 运算符重载的性感示例。

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

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

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

您可以在此处此处找到更多详细信息和示例。

HTH。

于 2012-09-04T04:00:26.703 回答