19

比較的初心者として、私は特定の主題についてできるだけ多くのことを読み、できるだけ多くのコードをテスト/作成しようとしています。私はJonsBrainteasersの1つ(質問#2)を見ていましたが、私の出力は答えとは異なりました。これにより、最近のバージョンで何かが変更されたかどうかを確認し、他の人がこのコードからどのような出力を取得しているかを確認することができます。

問題は、「何が表示されるのか、なぜ、そしてどの程度自信があるのか​​」です。

using System;

class Foo
{
    static Foo()
    {
        Console.WriteLine ("Foo");
    }
}

class Bar
{
    static int i = Init();

    static int Init()
    {
        Console.WriteLine("Bar");
        return 0;
    }
}

class Test
{
    static void Main()
    {
        Foo f = new Foo();
        Bar b = new Bar();
    }
}

どちらかといえば、2つの異なる答えが得られる原因は何でしょうか。

4

5 に答える 5

25

次に、デバッガーの外部でリリースモードで試してください;-p

デバッガーの有無にかかわらず、異なる結果が得られます。デバッガーは多くの微妙なニュアンス/最適化を混乱させるので、これはデバッガーが重要な時間の1つであると推測できます。これにより、デバッグがさらに困難になります;-p

于 2009-10-29T17:22:38.633 に答える
6

ジョン自身の回答ページでこれについて説明しています。私はC#の人ではありませんが、システムには静的fooコードを呼び出すタイミングを1つだけ選択できるようです(したがって、「Foo」と記述します)が、初期化するタイミングを決定する自由は基本的に無限ですBar.i(「Bar」と記述します)。 ")なので、クラスがロードされたとき、最初に使用されたとき、またはまったく発生しない可能性があります。

于 2009-10-29T17:21:44.333 に答える
4

Foo、Barをデバッグモードで、Bar、Fooをリリースモードで印刷します。つまり、リリースコードが最適化され、最適化によってBarが最初に呼び出されるようになりますが、常にそうであるという保証はありません。

于 2009-10-29T17:24:06.007 に答える
0

見ているだけで「FooBar」以外が表示されているとびっくりします。

単純な理由で、最初にFooにアクセスしているため、静的コンストラクターが実行されます。Barをインスタンス化するときに、静的フィールド初期化子が続きます。

訂正させていただきます。

于 2009-10-29T17:21:49.693 に答える
0

fooバーが印刷されると思います。静的型コンストラクターは最初にFooで実行され、次にInitメソッドがBarクラスで呼び出されます。でも、振る舞いが変わるかどうかはわかりません。これは面白い。

于 2009-10-29T17:28:40.483 に答える