1. ホーム
  2. c#

[解決済み] なぜ、(j++);という記述が禁じられたのですか?

2022-04-23 17:31:21

質問

以下のコードは間違っています(参照 アイデア次第で ):

public class Test
{
    public static void Main()
    {
        int j = 5;
        (j++);      // if we remove the "(" and ")" then this compiles fine.
    }
}

エラー CS0201: 代入、呼び出し、インクリメント、デクリメント、await、および 新規オブジェクト式は、ステートメントとして使用することができます。

  1. なぜ括弧を取り除くとコードがコンパイルされるのですか?
  2. なぜ、括弧があるとコンパイルできないのですか?
  3. なぜC#はそのように設計されたのですか?

どうすれば解決するの?

<ブロッククオート

深い洞察に感謝します。

がんばります。

他の回答者が指摘しているように、ここで起こっていることは、コンパイラが として使用されています。 ステートメント . CやJavaScriptなど多くの言語では、式を文として使うことは完全に合法です。 2 + 2; はこれらの言語では合法であり、これは何の効果もない文である。いくつかの式はその値に対してのみ有効であり、いくつかの式はその副作用(例えばvoid returnメソッドの呼び出し)に対してのみ有効であり、残念ながらいくつかの式は両方に対して有効です。(インクリメントのような)

ポイント:式だけで構成された文はほぼ間違いなくエラーになる ただし、それらの式が値よりもその副作用のために有用であると一般的に考えられている場合は除きます。 . C#の設計者は、一般的に副作用があると考えられている式を許可する一方で、一般的にその値が有用であると考えられている式を禁止することで、その中間を見つけようとしました。 C#1.0では、インクリメント、デクリメント、メソッドコール、アサインメント、そして少し物議を醸したコンストラクタの起動がその対象となりました。


ASIDE 通常、オブジェクトの構築は、構築の副作用ではなく、それが生み出す価値のために使用されると考えるのが普通だと思います。 new Foo(); は、ちょっとしたミスフィーチャーです。特に、実際のコードでこのパターンを見て、セキュリティ上の欠陥が発生したことがあります。

catch(FooException ex) { new BarException(ex); } 

コードが複雑な場合、この不具合を発見するのは意外と難しいかもしれません。


そのため、コンパイラはこのリストにない式で構成されるすべてのステートメントを検出するように動作します。特に、括弧でくくられた式は、そのまま括弧でくくられた式として認識されます。 これらは、quot;ステートメント式として許可される" のリストにないので、許可されません。

これらはすべて、C#言語の設計原則のためにある。 もし、あなたが (x++); おそらく、何か間違ったことをしているのでしょう。 . のタイプミスであろう。 M(x++); とか、そういうことです。C#コンパイラーチームの姿勢は、"ではないことを覚えておいてください。 どうにかして、これを動かす方法はないだろうか? C#コンパイラーチームの姿勢は、「" もっともらしいコードが間違いの可能性が高そうなら、開発者に知らせよう。 ということです。 C#の開発者はそのような姿勢が好きなのです。

さて、そうは言っても、実はC#の仕様で奇妙なケースがいくつかあります。 する C#コンパイラは、括弧を使用しないことを暗示または明示しているにもかかわらず、括弧を許可します。ほとんどすべての場合において、指定された動作と許可された動作の間のわずかな不一致はまったく無害なので、コンパイラの作者はこれらの小さなバグを修正したことがありません。これらのバグについては、ここで読むことができます。

return myVarとreturn (myVar)は違うのですか?