是否可以在 C# 中创建一个新的运算符?
Posted
技术标签:
【中文标题】是否可以在 C# 中创建一个新的运算符?【英文标题】:Is it possible to create a new operator in c#? 【发布时间】:2010-11-05 14:56:29 【问题描述】:我知道您可以重载现有的运算符。我想知道是否可以创建一个新的运算符。这是我的场景。
我想要这个:
var x = (y < z) ? y : z;
等价于这个:
var x = y <? z;
换句话说,我想创建自己的<?
运算符。
【问题讨论】:
没有语言有这个能力... @JesonPark - 不正确。正如其他人指出的那样,F# 拥有它,C++ has it as well. CoffeeScript 提供了几个新的运算符作为 javascript 惯用语的语法糖,而且它是如此可定制,以至于您可以将其描述为允许自定义运算符。最后一个有点棘手,因为从技术上讲,您会扩展语言。 @JustinMorgan: CodeProject 文章中提到“C++ 支持运算符重载,但你不能创建自己的运算符” 这是仿真!! 即使有可能,我仍然认为这不是一个好主意。它比方法可读性差得多,例如Min(y, z)
.
@userSteve 这已被提议用于 C# 8 - null coalescing assignment
【参考方案1】:
我很惊讶没有人提到"order of operations"
。
当编译器评估一个表达式时,它必须关注以正确的顺序执行操作,以便(1+2*3) = (2*3+1)
乘法总是发生在表达式中相同的"level"
加法之前。
当您覆盖 and 运算符时,您可以更改运算符的作用,但不能更改编译器评估它的顺序。如果您确实创建了一个新的运算符,则无法告诉编译器相对于其他运算符来评估它的顺序。所以如果你写x <? 2 + 5
,你是先执行x <? 2
然后加5还是先执行加法然后再执行x <? 7
。
【讨论】:
【参考方案2】:不,但您可以在 C# 中重载 some existing operators。
在其他一些语言中,例如 F#,您可以使用:
let (<?) = min
【讨论】:
其实应该是最小值,而不是最大值;)【参考方案3】:您可以尝试重载其他运算符,例如 %
或 +
以充当 <?
运算符。
会很有趣
【讨论】:
这不是他问题的答案。 不,这不是一个答案,但它以某种方式说明了它可能会进化到多么荒谬......【参考方案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;
但我有点像? : 垃圾。
好的代码不仅紧凑高效,而且可读性强。即使你是唯一一个读过它的人,你总有一天会回到那个 <?
运算符,想知道它到底做了什么。
【讨论】:
如果它是另一种语言的已知功能,就像这个问题问的那样:***.com/questions/523403/… 任何运算符重载都可以这样说 我不同意。我认为运算符重载在很多情况下都是有意义的。例如,如果将一个类型的两个实例加在一起有意义,您可能希望重载 + 运算符而不是创建 .Add() 方法。直觉上,有人看到“+”,他们就明白运算符是在算术上将这两个东西加在一起。如果这就是重载有效的作用,那么它很容易理解。 我想使用====
,以便我的整个开发团队都知道我们正在为该特定对象使用覆盖测试。就是这样,但是是的.. 我想避免的是在 if 中使用方法.. 只是搞砸了。【参考方案6】:
正如其他答案所说,您不能创建新的运算符 - 至少,如果不更改编译器内置的词法分析器和解析器,则不能。基本上,编译器的构建是为了识别像<
或?
这样的单个字符,或者像>>
或<=
这样的一对,是一个运算符并对其进行特殊处理;例如,它知道i<5
是一个表达式而不是变量名。将运算符识别为运算符与决定运算符实际执行的操作是分开的过程,并且与编译器的集成更加紧密 - 这就是为什么您可以自定义后者而不是前者的原因。
对于具有开源编译器的语言(例如 GCC),理论上您可以修改编译器以识别新的运算符。但这并不是特别容易,而且每个人都需要您的自定义编译器来使用您的代码。
【讨论】:
只是为了清楚起见,在 C++ 中人们使用宏来做这样的事情?我不懂C++,只是问问。 或者只使用运算符是中缀方法的语言,例如 scala 或 f#【参考方案7】:不,这是不可能的。你需要创建一个方法来代替
【讨论】:
以上是关于是否可以在 C# 中创建一个新的运算符?的主要内容,如果未能解决你的问题,请参考以下文章