2011-10-15 7 views
51

C#およびC++/CLIでは、どのような継承チャンスからでもクラスを保護するために、キーワードsealed(またはVBではNotInheritable)が使用されます(クラスは継承できません)。私は、オブジェクト指向プログラミングの1つの機能が継承であることを知っています。sealedの使用がこの機能に逆らっていると感じ、継承を停止します。 sealedのメリットとそれを使用することが重要な場合の例がありますか?いつ、なぜあなたはクラスを封印しますか?

答えて

62

1)セキュリティ機能を実装するクラスで、元のオブジェクトを「偽装」できないようにします。

2)より一般的には、私は最近、未処理のまま放置するとパフォーマンスが高くなるため、実際に完全に理解できる場所に継承を制限しようとしているとマイクロソフトで話しました。
sealedキーワードは、CLRに、メソッドを探すためのクラスがなくなっていることを通知します。これにより処理が高速化されます。

現在市場に出回っているほとんどのパフォーマンス向上ツールでは、継承されていないすべてのクラスをシールするチェックボックスがあります。
MEFを使用してプラグインまたはアセンブリの検出を許可する場合は、問題が発生するため、注意してください。

+0

封印されたクラスを使用している場合、なぜMEFに問題がありますか? –

+3

私は再利用されたライブラリのクラスを密封することに注意しなければなりません。特に、それらが第三者によって再利用され、その後(MEFを介して)コードベースに再統合される場合には注意が必要です。あなたのコードベースは与えられたクラスを継承することはできませんが、第三者はそれを継承します。 –

+0

理由#1が曖昧に聞こえますが、ほとんどの場合「セキュリティ機能」を書いていないと仮定すると、理由#1はほとんど適用されません。理由#2はパフォーマンスチューニングのためのものです。パフォーマンスの違いはどれくらいですか?非セキュリティクラスの定義を変更することを正当化するのに十分重要ですか?答えが「はい」であっても、これは開発者にコードベースを変更させるのではなく、理想的にはコンパイラオプション、つまり「非密閉クラスすべてに対して最適化されたコードを生成する」でしょう。 – RayLuo

7

ヒヒの優れた答えに補遺:

3)クラスを継承するためにを設計されていないされている場合は、サブクラスはclass invariantsを壊すかもしれません。これは実際には公開APIを作成する場合にのみ当てはまりますが、私は親指のルールとして、サブクラス化するように明示的に設計されていないクラスはすべて封印します。

封印されていないクラスのみに適用されます。virtualを作成した方法は、拡張ポイントであるか、少なくとも拡張ポイントである必要があります。宣言方法virtualもまた意識的な決定でなければなりません。 (C#では、これは意識的な決定であり、Javaではそうではありません。)


EDIT:いくつかの関連リンク:ジョシュアブロッホ

はまた、デフォルトではそのKotlinシールクラスを注意してください。 its open keyword is the opposite of Java's final or the sealed of C#。 (確かに、there is no universal agreement that this is a good thing。)

+8

シールクラスは、利益よりも頭痛を引き起こします。私は、開発者がクラスを封印した状況を絶えず見つけ、何が簡単なのか何時間も問題になっていました。 封筒のクラスをやめることは、あなたが思っているほど上品ではありません。あなたがしなければならない場合にのみ、そしてその後でさえ、再考してください。 他の人の封印されたクラスに対処しなければならない人として私は編集/開封できません。 – GantMan

+2

@GantManのコメントは、OPの質問への答えの1つと考えるべきです。なぜなら、「いつ?ほとんどないのですか?これはあなたがそれをしない理由です」。あなたは別の答えとしてあなたのコメントを再投稿し、投票を集めるべきです。 :-) – RayLuo

-1

私はこのポストはいくつかの良い点を持っていると思う、具体的なケースは、任意のランダムなインターフェイスに非密封クラスをキャストしようとしたとき、コンパイラはエラーをスローされませんでした。しかし、sealedを使用すると、コンパイラは変換できないエラーをスローします。 Sealedクラスは、コードアクセスのセキュリティを強化します。
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla

+1

解決策へのリンクは歓迎しますが、あなたの答えがそれなしで役に立つことを確認してください:[リンクの前後にコンテキストを追加](// meta.stackexchange.com/a/8259)それが何で、なぜそこにあるのか、ターゲットページが利用できない場合にリンクしているページの最も関連性の高い部分を引用します。 [リンクよりも少しだけ回答が削除される可能性があります。](// stackoverflow.com/help/deleted-answers) –

+0

申し訳ありませんが、回答として投稿するつもりはありませんでしたが、他の回答と関連していないようです。それを置く場所を知らない – strisunshine

+0

私は提案に従って投稿を編集しました。もともと私はちょうど別の角度(多分)に貢献したいと思っていますが、私はdownvoteを持っていて、まだ内容について話していませんでした。 – strisunshine

関連する問題