【问题标题】:Treat an Operator as Object将运算符视为对象
【发布时间】:2012-09-03 16:22:28
【问题描述】:

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

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

据我所知,(感谢 Google),overload an operator 是可能的,但我找不到其他任何东西。

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

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

只是我好奇的问题,与我的工作无关。

【问题讨论】:

  • 不,这是不可能的。
  • 你的意思是public seal class +{...} ??那么1+2 会做什么???
  • 正如我向 Jon Skeet 提到的,假设我想这样做 if(+.PrecedenceLevel > *.PrecedenceLevel) {something} 但你说得对,我没有考虑 1+2会做。但我想这只是实现,对吧?我的意思是,在 Smalltalk 中,据我所知,这是可能的
  • @ElVieejo:- 除了这个if(+.PrecedenceLevel > *.PrecedenceLevel) {something} 概念真的很好,希望有一天有人会实现:) :thumbsup:

标签: c# oop object operators


【解决方案1】:

重载的操作符是静态方法,因此有对应的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# 中的==,@987654324 @in VB.NET 等),它的优先级或任何“操作性”可以这么说。

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

【讨论】:

  • 我不知道.Net 会这样对待操作员。很有趣!
  • @ElVieejo 再次不过,只有重载。 1 + 2+ 不能以这种方式访问​​,因为它是用语言而不是 BCL 定义的。同样,虽然这告诉我们一种语言可能会给它一个“特殊名称”,但它并没有告诉我们 C# 有,或者该名称是 ==
【解决方案2】:

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

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

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

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

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

HTH。

【讨论】:

  • 这很有趣。听说过表达式树,但没用过,也不知道怎么用。谢谢 ! +1
猜你喜欢
  • 1970-01-01
  • 2015-11-15
  • 2017-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-05
  • 1970-01-01
相关资源
最近更新 更多