web-dev-qa-db-ja.com

C#で新しい演算子を作成することは可能ですか?

既存のオペレーターをオーバーロードできることを知っています。新しいオペレーターを作成できるかどうか知りたい。これが私のシナリオです。

これ欲しい:

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

これと同等になるには:

var x = y <? z;

つまり、自分で<?演算子。

59
Aaron Palmer

いいえ、できません。代わりにメソッドを作成する必要があります

39
AgileJon

いいえ、ただしC#では 一部の既存の演算子 をオーバーロードできます。

F#などの他の言語では、次の言語を使用できます。

let (<?) = min
31
Dario

他の答えが言ったように、新しい演算子を作成することはできません-少なくとも、コンパイラーに組み込まれているレクサーとパーサーを変更しない限りは。基本的に、コンパイラは、<?のような個々の文字、または>>または<=のようなペアが演算子であることを認識し、それを特別に扱うように構築されています。たとえば、i<5は変数名ではなく式であることがわかります。オペレーターをオペレーターとして認識することは、オペレーターが実際に何をするかを決定することとは別のプロセスであり、コンパイラーにより密接に統合されています。そのため、前者ではなく後者をカスタマイズできます。

オープンソースのコンパイラー(GCCなど)を備えた言語の場合、理論的には、コンパイラーを変更して新しい演算子を認識できます。しかし、それは特に簡単なことではありません。また、コードを使用するにはカスタムコンパイラが必要です。

17
David Z

それができないだけでなく、なぜあなたはそうしたいのですか?

あなたのyとzのタイプはわかりませんが、数値タイプの場合は、おそらく次のように使用できます。

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

個人的には、私はまだ好むでしょう:

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

しかし、私は少しですか? :ジャンキー。

優れたコードは、タイトで効率的であるだけでなく、読み取り可能でもあります。あなたがそれを読んだ唯一の人であったとしても、あなたはそれに戻るでしょう<?ある日オペレーターが何をしていたのか不思議に思いました。

5
Paul Hooper

いいえ、ただし、これの代わりに拡張メソッドを作成できます

y.MethodName(z)
5
Rony

"order of operations"について誰も言及していないことに驚いています。

コンパイラが式を評価するときは、演算を正しい順序で実行することに注意する必要があります。これにより、式の同じ(1+2*3) = (2*3+1)で加算する前に"level"乗算が常に発生します。

オーバーライドして演算子を使用すると、演算子の動作を変更できますが、コンパイラが演算子を評価する順序は変更できません。新しい演算子を作成した場合、他の演算子と比較してそれを評価する順序をコンパイラーに指示する方法はありません。したがって、x <? 2 + 5と書いた場合、x <? 2firstを実行してから5を追加するか、最初に追加を実行してからx <? 7を実行しますか。

2
Jeff