2

特定のディレクトリ内のすべてのファイルのリストを取得したい場合は、次のように入力できます。

var files = (new DirectoryInfo(@"C:\Temp")).GetFiles();

ただし、以下も機能します(「new」キーワードの前に括弧がないことに注意してください)。

var files = new DirectoryInfo(@"C:\Temp").GetFiles();

なぜこれが起こるのを許されているのですか?次のようなステートメント:

2 + 4 * 3   and   (2 + 4) * 3

括弧があるため、それぞれ14と18に解決されます。

私のコード例は、静的バージョンのDirectoryInfoオブジェクトで「.GetFiles()」メソッドを呼び出すのに似ているようです(「new」キーワードがないため)。ここで、括弧は「new」キーワードと組み合わされています。 DirectoryInfoオブジェクトのインスタンスを使用していることを明示します。

すなわち:

2   +  4               * 3
new    DirectoryInfo()   .GetFiles()

vs:

(2   +  4              ) * 3
(new    DirectoryInfo())   .GetFiles()

これが事実である理由の簡単な説明はありますか?C#レクサーが両方のケース(括弧付き/なし)を処理するのはもっと手間がかかりませんか?私のアナロジーには欠陥がありますか?

4

5 に答える 5

8

注:この回答には、互いに同等の表現がたくさんあります。<==>インラインのままにしたり、2つの別々の行に分割したりするのではなく、「と同等」を意味する略記を採用しました。それで

foo   <==>   bar

foo「式は式と同等です」と読む必要がありますbar

あなたが話しているのは優先順位です。*二項演算子よりも優先順位が高い+ため、「オペランドをより厳密にバインド」します。それで:

 x * y + z   <==>   (x * y) + z

newと「ドット」の部分はどちらも主要な式であり、優先順位は同じです。2つの形式の優先順位が同じである場合、結合性が関与します。C#の仕様は、演算子に関しては実際にはそれほど明確ではありませんnewが、.演算子は2項演算子であり、すべての2項演算子は左結合であると見なされます。言い換えると:

x.y.z   <==>   (x.y).z

別の例として、同じ優先順位*を持っているので、次のようになります。/

x * y / z   <==>   (x * y) / z
x / y * z   <==>   (x / y) * z

したがって:

new DirectoryInfo(x).GetFiles()   <==>   (new DirectoryInfo()).GetFiles()

これらはすべて、常に左から右に配置される評価順序とは多少異なります。たとえば、式x + y * zで、の優先順位が高いということは、次のことを*意味します。

x + y * z   <==>   x + (y * z)

...しかし、それでもx最初に評価され、次にyz次に乗算、最後に加算が評価されます。いつものように、EricLippertはこのトピックについて非常によく書いています

于 2012-11-26T21:06:55.937 に答える
4

優先順位については、MSDNの記事を参照してください: 7.2.1

すべての非割り当て二項演算子は結合性のままであるため、同じように先行する演算子new.演算子は左から右に評価されます。

したがって、指定された式では、オブジェクトはそのメソッドが呼び出される前にインスタンス化されます。また、 -newは同等の優先順位を持っているため、取得する前に型識別子(左から右)を消費し.ます。

于 2012-11-26T21:02:02.260 に答える
3

静的メソッドを呼び出すための構文はそうではDirectoryInfo.GetFiles()ないDirectoryInfo(...).GetFiles()ので、これら2つの解釈の間にどのように競合が発生する可能性があるのか​​わかりません。

いずれにせよ、乗算は加算または減算よりも優先されるため、数式を使用した例では、最初に3を乗算します。括弧が行うのは、デフォルトの優先順位をオーバーライドできるようにすることだけです。

静的メソッドを呼び出すための構文が同じであっても、質問した場合、デフォルトの優先順位により、括弧なしで期待どおりに機能します。

于 2012-11-26T20:57:59.093 に答える
2

戻り値を返すことはできないnewため、コンパイラーは、初期化された型でnewを配置し、新しいインスタンスでメソッドを実行することを認識しています。

(new A()).Foo() // Makes sense! sort of...
new (A().Foo()) // Makes absolute no sense.

(1 + 4) * 10 // Makes sense
1 + (4 * 10) // Also makes sense

数字とC#キーワードの間で物事がどのように連携するかという論理には違いがあります。

于 2012-11-26T20:59:18.440 に答える
1

あなたのアナロジーは、数学の演算の優先順位については問題ありません。しかし、構文的にnewを使用すると、クラスの「new」インスタンスの準備ができるようにコンパイラーに指示されます。括弧の有無にかかわらず、キーワードnewを使用して、そのクラスの新しいインスタンスがあります。

于 2012-11-26T20:58:59.303 に答える