5

私は小さなプロジェクト用の単純なクラスを作成していて、を使用する代わりにクイックimplのデストラクタを追加することにしIDisposableました。アクセス修飾子が付いたデストラクタがあると、コンパイラエラーが発生しました。

public class MyClass
{
    public ~MyClass()
    {
        // clean resources
    }
}

私はパブリック、プライベート、プロテクト、そして内部を試しました。アクセス修飾子がなくても正常に機能しました。この記事は、〜destructorが本質的に保護されたFinalize関数のシンタティックシュガーであることを示しているので、少なくともデストラクタで保護されたものを使用できないのは奇妙なことです。記事には、「デストラクタを呼び出すことはできません。デストラクタは自動的に呼び出されます」と記載されています。これは、その動作が強制される方法ですか?

とにかく実装することになりましたIDisposableが、興味があります...デストラクタにアクセス修飾子を配置できない理由は他にありますか?

4

4 に答える 4

18

ソースコードで宣言されたメンバーのアクセシビリティドメインは、そのメンバーにアクセスできるプログラムテキストのすべてのセクションのセットで構成されます。

アクセシビリティ修飾子は、アクセシビリティドメインのコンテンツを変更します。

アクセシビリティ修飾子に関する興味深い事実は、アクセシビリティ修飾子が常にアクセシビリティドメインを大きくするか、同じサイズに保つことです。アクセシビリティモディファイアは、アクセシビリティドメインを小さくすることはありません。

デストラクタのアクセシビリティドメインは常に空であることが望まれます。つまり、プログラムテキストのどの領域でもデストラクタにアクセスすることは決して合法ではありません。

この理由は、特定のインスタンスのデストラクタがオブジェクトのライフタイムの最後に1回だけ実行されるという、強制された不変条件を提供したいためです。(ファイナライズ中のデッドオブジェクトの「復活」は、後日説明する興味深い問題を引き起こします。)デストラクタへのアクセスを禁止することにより、ユーザーコードがデストラクタを早期に呼び出さないようにします。

したがって、ユーザーがアクセシビリティドメインのサイズを大きくできるようにするのは愚かなことです。言語の設計のこの慎重に検討された側面を打ち負かすためのツールをユーザーに渡したくはありません。

この安全機能を無効にしますかなんで?プログラムテキストのある領域からデストラクタを呼び出すことができることが重要であるシナリオを説明できますか?

デストラクタは本質的に、保護されたファイナライズ機能のためのシンタティックシュガーです

正しい。仕様では、セクション10.13でこれに注意しています。また、保護されているとされる「 Finalize」メソッドのアクセシビリティドメインも空であることに注意してください。オーバーライドも呼び出しもできません。

デストラクタを実装するためにまったく異なるメカニズムを選択することもできましたが、それが私たちが選択したメカニズムです。デストラクタ機能の特定の実装戦略をたまたま選択したという事実は、安全上の理由から、デストラクタのアクセシビリティドメインを強制的に空のままにしておく必要があるという事実とは特に関係ありません。

于 2010-03-06T00:07:42.083 に答える
16

アクセス修飾子は、ユーザー作成コードのどのスコープがメソッドを呼び出すことができるかを制御します。

publicつまり、ユーザーが作成したコードであれば、メソッドなどを呼び出すことができます。

ただし、デストラクタはユーザー作成コードによって呼び出されません。デストラクタはGCによって自動的に呼び出されます。アクセス修飾子は、GCにとって何の意味もありません。

したがって、メソッドにアクセス修飾子を設定しても意味がありません。アクセスできず、そのアクセスを変更することもできません。

デストラクタへのアクセスは「スーパープライベート」であると考える方がよいでしょう。オブジェクト自体でさえ、誰も実際にデストラクタを呼び出すことはできません。

于 2010-03-05T23:02:47.810 に答える
6

ご指摘のとおり、「デストラクタは呼び出せません。自動的に呼び出されます」からです。

アクセスできないものにアクセス修飾子を設定しても意味がありません。

于 2010-03-05T23:02:31.523 に答える
0

DisposablePatternを使用する必要があります。

C#でパターンを完成/破棄します

于 2010-03-06T01:50:02.507 に答える