2

別のトピックでは、いい人がエリック・リッパートの言葉を引用して私に言った:静的の重要性は、コンパイラが特定のクラス/構造体/フィールドのコンパイル時に持っている知識と確実性に関係しています。それはメモリの場所とは関係がなく、それらが修正されているかどうかなどです。

しかし、コンパイラーは以下に示すようなことが起こることを許可しているので、私はまだよくわかりません。

        struct MyStruct
        {
             public static int[] Arr = {1,3,5};
        }
        static void Test<T>(ref T t) where T:struct
        {
            Console.WriteLine (t);
        }
        void Main()
        {
            Test(ref MyStruct.Arr[2]);//output: as expected 5
        }

ref引数はc++参照とはまったく異なるものですか、それともいくつかの引数がrefによって渡されるたびに舞台裏のピンが発生しますか?静的メンバーが移動可能である場合、ランタイムは、呼び出された関数の実行中に配列要素のアドレスが変更されないことをどのように保証しますか?実験から、オブジェクトの戻り値「配列以外のアイテムプロップ」はRefによって渡されないことがわかりました。これは、配列要素が連続メモリのチャンクに割り当てられているためだと思いましたが、配列全体が移動可能である場合、どのようにしてその要素のアドレスを取得できますか?

私はこの不確実性にちょっと立ち往生しています。誰かが特定の答えを与えることができれば、私は非常に感謝しています。前もって感謝します!

~~~~~~~~~~~~~~~~~~

それを理解しようとしています:

ですから、コンパイラーがそれを可能にする限り、どんな管理された操作でも、私たちはそれを発汗させるべきではありませんよね?私はC/C ++のバックグラウンドを持っていますが、C ++の「静的」の意味はかなりよく理解していると思います。マネージコードの移動性だけが、私を疑わしくさせます。スタックまたはマネージヒープにあるかどうかに関係なく、任意のマネージドオブジェクトは、refargが常に正しくポイントすることができます。

4

1 に答える 1

4

C#ref引数はC ++参照と完全に異なるわけではありませんが、この点で異なります。

C#ref引数はガベージコレクターに認識されており、オブジェクトを別の世代にプロモートする場合はそれらを調整します。

C ++参照は、.NETガベージコレクターには表示されません。ターゲットが固定されておらず、ガベージコレクターが実行されている場合、C++参照は壊れます。

(C ++ / CLIは.NET参照とネイティブ参照の両方をサポートします)

静的メンバーが移動可能である場合、ランタイムは、呼び出された関数の実行中に配列要素のアドレスが変更されないことをどのように保証しますか?

そうではありません。ただし、関数は.NETコードでもあるため、更新されたアドレスを使用します。

そして、配列を参照する静的フィールドがあるかどうかによって、これは何も変わりません。(実際、配列自体は静的ではなく、それを参照しているフィールドのみです。この事実により、質問全体が無意味になります。)

于 2011-07-31T01:58:41.853 に答える