0

簡単な質問です。

このコードを検討してください

public class Tile
{
    public Collision Collision;
    public Tile()
    {
        Collision = new Collision(this);
    }
    public ~Tile()
    {
        CollisionHandler.Remove(Collision);
    }
}

public class Collision
{
    public Collision()
    {
        CollisionHandler.Add(this);
    }
}

public class Main
{
    public Main()
    {
        Test1();
        Test2();
    }

    public void Test1()
    {
        Tile[,] tiles = new Tile[20,20];
        tiles[0,0] = new Tile();

        tiles[0,0] = new Tile();
        //Would calling the above call the old Tile's destructor?
    }

    public void Test2()
    {
        Tile[,] tiles = new Tile[20,20];
        tiles[0,0] = new Tile();

        Tile t = new Tile();
        tiles[0,0] = t
        //Would calling the above call the old Tile's destructor?
    }
}

さて、実行Test1すると oldTileのファイナライザが呼び出されますか? どうTest2ですか?

4

3 に答える 3

3

答えはノーだ。

オブジェクトは、ガベージ コレクターが必要と判断するまでファイナライズされません。この時点で、C++ のようなリモートで何かを行っているわけではありませんdelete。メモリの新しい部分を割り当てて、ポインターを変更しているだけです (大まかに)。

コメントで述べたように: ファイナライザー (C#) とデストラクタ (C++) は同じではありません。

于 2013-06-17T04:28:46.200 に答える
1

C# のデストラクタ (正式名称は「ファイナライザ」) については、いつ呼び出されるかわからないということです。オブジェクトが範囲外になるとすぐに呼び出すことができます。プログラムの終了時に呼び出すことができます。場合によっては、まったく呼び出されないことさえあります。それはすべてガベージコレクター次第です。

そのため、システム ロジックにデストラクタを使用しないでください。デストラクタを使用する必要がある状況はそれほど多くありません。

于 2013-06-17T04:29:13.720 に答える
0

あなたのコードは不完全です。それが完成した場合、参照オブジェクトは のように連鎖されるCollisionHandler->Collision->Tileため、無視Tileされたものはガベージコレクターによって収集されることはありません。

.NET GC は非決定論的であるため、自動的に管理される決定論的デストラクタのようなものを探している場合は運が悪いです。.NET フレームワークはIDispose、ファイル I/O 操作などの決定論的なクリーンアップが優先される状況向けのインターフェイスを提供しますが、消費者はこれを認識してDispose明示的に呼び出すかusing、C# のキーワードのような言語の機能を使用して呼び出す必要があります。

于 2013-06-17T04:46:41.273 に答える