【问题标题】:Is it possible to create a new operator in c#?是否可以在 C# 中创建一个新的运算符?
【发布时间】:2010-11-05 14:56:29
【问题描述】:

我知道您可以重载现有的运算符。我想知道是否可以创建一个新的运算符。这是我的场景。

我想要这个:

var x = (y < z) ? y : z;

等价于这个:

var x = y <? z;

换句话说,我想创建自己的&lt;? 运算符。

【问题讨论】:

  • 没有语言有这个能力...
  • @JesonPark - 不正确。正如其他人指出的那样,F# 拥有它,C++ has it as well. CoffeeScript 提供了几个新的运算符作为 JavaScript 惯用语的语法糖,而且它是如此可定制,以至于您可以将其描述为允许自定义运算符。最后一个有点棘手,因为从技术上讲,您会扩展语言。
  • @JustinMorgan: CodeProject 文章中提到“C++ 支持运算符重载,但你不能创建自己的运算符” 这是仿真!!
  • 即使有可能,我仍然认为这不是一个好主意。它比方法可读性差得多,例如Min(y, z).
  • @userSteve 这已被提议用于 C# 8 - null coalescing assignment

标签: c# .net operators


【解决方案1】:

我很惊讶没有人提到"order of operations"

当编译器评估一个表达式时,它必须关注以正确的顺序执行操作,以便(1+2*3) = (2*3+1) 乘法总是发生在表达式中相同的"level" 加法之前。

当您覆盖 and 运算符时,您可以更改运算符的作用,但不能更改编译器评估它的顺序。如果您确实创建了一个新的运算符,则无法告诉编译器相对于其他运算符来评估它的顺序。所以如果你写x &lt;? 2 + 5,你是先执行x &lt;? 2然后加5还是先执行加法然后再执行x &lt;? 7

【讨论】:

    【解决方案2】:

    不,但您可以在 C# 中重载 some existing operators

    在其他一些语言中,例如 F#,您可以使用:

    let (<?) = min
    

    【讨论】:

    • 其实应该是最小值,而不是最大值;)
    【解决方案3】:

    您可以尝试重载其他运算符,例如 %+ 以充当 &lt;? 运算符。

    会很有趣

    【讨论】:

    • 这不是他问题的答案。
    • 不,这不是一个答案,但它以某种方式说明了它可能会进化到多么荒谬......
    【解决方案4】:

    不,但您可以创建扩展方法而不是这个

    y.MethodName(z)
    

    【讨论】:

    • 2.IfNotSmallEnoughThen(1) :)
    • 我这里有 true.Xor(false)... :(
    【解决方案5】:

    你不仅不能这样做,而且你为什么要这样做?

    我不确定你的 y 和 z 是什么类型,但如果它们是数值类型,你可能会使用:

    var x = Math.Min(y, z);
    

    虽然就个人而言,我还是更喜欢:

    var x = (y < z) ? y : z;
    

    但我有点像? : 垃圾。

    好的代码不仅紧凑高效,而且可读性强。即使你是唯一一个读过它的人,你总有一天会回到那个 &lt;? 运算符,想知道它到底做了什么。

    【讨论】:

    • 如果它是另一种语言的已知功能,就像这个问题问的那样:stackoverflow.com/questions/523403/…
    • 任何运算符重载都可以这样说
    • 我不同意。我认为运算符重载在很多情况下都是有意义的。例如,如果将一个类型的两个实例加在一起有意义,您可能希望重载 + 运算符而不是创建 .Add() 方法。直觉上,有人看到“+”,他们就明白运算符是在算术上将这两个东西加在一起。如果这就是重载有效的作用,那么它很容易理解。
    • 我想使用====,以便我的整个开发团队都知道我们正在为该特定对象使用覆盖测试。就是这样,但是是的.. 我想避免的是在 if 中使用方法.. 只是搞砸了。
    【解决方案6】:

    正如其他答案所说,您不能创建新的运算符 - 至少,如果不更改编译器内置的词法分析器和解析器,则不能。基本上,编译器的构建是为了识别像&lt;? 这样的单个字符,或者像&gt;&gt;&lt;= 这样的一对,是一个运算符并对其进行特殊处理;例如,它知道i&lt;5 是一个表达式而不是变量名。将运算符识别为运算符与决定运算符实际执行的操作是分开的过程,并且与编译器的集成更加紧密 - 这就是为什么您可以自定义后者而不是前者的原因。

    对于具有开源编译器的语言(例如 GCC),理论上您可以修改编译器以识别新的运算符。但这并不是特别容易,而且每个人都需要您的自定义编译器来使用您的代码。

    【讨论】:

    • 只是为了清楚起见,在 C++ 中人们使用宏来做这样的事情?我不懂C++,只是问问。
    • 或者只使用运算符是中缀方法的语言,例如 scala 或 f#
    【解决方案7】:

    不,这是不可能的。你需要创建一个方法来代替

    【讨论】:

      猜你喜欢
      • 2012-01-15
      • 1970-01-01
      • 2018-04-27
      • 2012-05-04
      • 1970-01-01
      • 2012-09-04
      • 1970-01-01
      相关资源
      最近更新 更多