2009-06-17 4 views
8

私は素晴らしいメソッドとプロパティをたくさん持っているサードパーティのC#クラスで作業しています - しかし、時間が経つにつれて、私は自分のメソッドとプロパティでそのクラスを拡張する必要があります。それは私のコードだった場合、私は基本クラスとしてそのクラスを使用し、自分のプロパティとメソッドを最上位に追加する - しかし、このクラスは内部のコンストラクタを持っています。 (私の意見では、最初にコンストラクタを内部に作るのは短く、サブクラス化する能力を制限するのはなぜですか?)内部コンストラクタを持つクラスから派生する方法はありますか?

私が考えることができる唯一のことは、単に呼び出されたクラスのメソッド/それらの - しかしそれはコードのエーカーであり、まあ、それはちょうど "感じ"しません。

このクラスの基本クラスを使用する方法はありますか?あなたのクラスは、あなたが継承するクラスと同じアセンブリに住んでいる場合のみ

+1

パート1:http://blogs.msdn.com/ericlippert/archive/2008/09/26/preventing-third-party-derivation-part-one.aspx –

+1

パート2:http://blogs.msdn .com/ericlippert/archive/2008/10/06/prevent-third-party-derivation-part-two.aspx –

答えて

0

私はあなたがサードパーティのクラスを中心に、独自のファサードを構築することができるかどうかについては説明しません。以前の著者はそうです、ライブラリはこれを許さない方法で設計することができます。特定の順序で初期化する必要のあるシングルトンを持つ結合クラスがいくつかあるとします。サードパーティの開発者が気にすることのない設計ミス(または機能)がたくさんあるかもしれません。その方法で彼らの図書館。あなたはの周りにラッパーを書く必要がありますが、あまりにも多くの方法がありますし、これをするのは良くありません手動で

私はまさにその問題

1に対処するための3つのソリューションを参照してください)私はあなたがすべき .NET 4.0の新しい「ダイナミック」タイプは、あなたが「コードのエーカーを」記述することなく、その問題を回避できるようになると仮定第三者クラスのインスタンスを動的キーワード を持つprivareメンバとしてクラスにカプセル化します。クラスはDynamicから派生するか、IDynamicObjectインターフェイスを実装する必要があります。あなたは#4.0 C、まあサードパーティのクラスのカプセル化されたインスタンスへのすべての呼び出し

を転送しますGetMember/SetMember機能を実装する必要がありますのは、他のソリューションに見てみましょう、未来である:

2)のコードを記述しないでください。かなりの数のパブリックメソッドがある場合は手動で(100以上)私は、リフレクションを使用してすべてのパブリックメンバーを見つけて、カプセル化されたインスタンスを呼び出すためのコードを自動的に生成する小さなコンソールアプリケーションを作成します。例

public type MethodName(params) 
{ 
    this.anInstanceOf3rdPartyClass.MethodName(params); 
} 

3)のためにあなたはなく、例えば、レッドゲート.NETリフレクターのための既存の反射ツールの助けを借りて、2と同じことを行うことができます。それは、すべてのクラスとメソッドの署名をリストするのに役立ちます。次に、これをWordに貼り付けて、単純なVBマクロを使用して、2と同じコードを生成させます。 備考:コードをコピーせずにメソッドシグネチャをコピーするとすぐに公開されます私はあなたがライセンス契約に違反するとは思わないが、とにかくそれは再チェックする価値がある

2

。内部コンストラクタは、抽象クラスの具体的な実装を、そのクラスを定義するアセンブリに限定します。内部コンストラクタを含むクラスは、アセンブリの外部でインスタンス化することはできません。

2

拡張メソッドのための完全なアプリケーションのような音:再コンパイル、新しい派生型を作成することなく、既存のタイプに 『メソッドを追加「拡張メソッドをすることができます』、またはそれ以外の場合は元の型を変更する

MSDN extension method docs

拡張メソッドは特別な種類の静的メソッドですが、拡張型のインスタンスメソッドであるかのように呼び出されます。C#とVisual Basicで記述されたクライアントコードの場合、拡張メソッドの呼び出しと実際にあるタイプで定義されています。

+0

あなたはすでにあなたと同じ方法で新しいことをしています。それに加えられた。 – Bruce

+0

拡張メソッドは、静的メソッドを使用できる場所でのみ有効です。また、拡張メソッドを含むクラスを含む名前空間も含める必要があります。 たとえば、状態を格納するプロパティを持つことができませんでした。 –

+0

状態について理解しています - 制限があります。私は静的メソッドに関するあなたのコメントを理解していません - 確かに、拡張メソッドは静的ですが、 'this'パラメータを介してオブジェクトインスタンスにアクセスできます。 – Bruce

2

クラスは内部コンストラクタを持ち、publicコンストラクタがない場合、それはそれはサブクラス化されるため、設計者が意図していなかったことを示唆しています。その場合は、カプセル化を使用するか、拡張メソッドを使用できます。

5

質問:「なぜサブクラス化する能力が制限されていますか?」

継承のために設計しているので、あなたのクラスから継承する他の開発者のために設計している場合は特に、注意が必要です。 Josh Bloch氏は、Effective Javaでは、継承を設計するか、継承を禁止する必要があると述べています。私の見解では、継承のために設計する正当な理由がない限り、あなたはあまり投機的ではありません。

クラスは実装可能なインターフェイスを実装していますか(ほとんどの呼び出しを元のインスタンスにプロキシすることによって可能性があります)多くの場合、ここではうまく答えていないことがよくあります。クラスに追加しようとしているものも含め、正確な状況に応じて最適なソリューションが決まります。

状態を追加していない場合は、効果的な方法で効果的に拡張メソッドを使用すると効果的です。しかし、オブジェクトが格納できるデータは変更されないので、独自の特殊なデータを追加する必要がある場合は動作しません。

1

Resharperは、委任するメンバーを作成するための素敵な機能があります。

Hereは、あなたができることのサンプルです。数秒かかります。

関連する問題