2009-09-04 9 views
0

私は今、私はこのカスタムサーバーコントロールをコピーする必要が場合がありますカスタムサーバーコントロールでMemberwiseClone()を呼び出すのは安全ですか?

public class MyCustomCtrl : WebControl 
{ 
    private Button innerCtrl; //some arbitrary object, doesn't matter 

    ... 

    protected override void CreateChildControls() 
    { 
     //initialization etc, as standard... 

    } 

} 

のように見えます(擬似コード)カスタムサーバーコントロールを書かれています。基本的には、プログラマがaspxまたはascxコードに宣言的に追加します。実行時に、このコントロールの複数のインスタンスを作成し、それを親コントロールに追加する必要があります。しかし、これはその親コン​​トロールのコンテキストで処理されます。

とにかく、使用のコンテキストを説明するのは少し難しいです。私の主な質問は、特に "クローン"を使用するのが安全かどうか、特にウェブコントロールでMemberwiseClone()を呼び出すことですか?私がこれまで行ったことは、次のようなメソッドを追加することです

public class MyCustomCtrl : WebControl 
{ 
    ... 

    public object Clone(){ 
     MyCustomCtrl clone = MemberwiseClone() as MyCustomCtrl; 
     clone.InnerCtrl = this.innerCtrl.Clone() as Button; //or whatever type 

     return clone; 
    } 
} 

つまり、ASP.netコントロール階層は非常に複雑なモデルです。だから私は、そのような解決策で発生するかもしれない欠点を知っている人がいるかどうか聞いてみたかったのです。

答えて

2

非常に一般的な理由から、これは安全な操作ではありません。MemberwiseCloneはディープコピーではなく、シャローコピーです。

ViewStateのようなものは、元のコントロールとクローンの間で共有されます。しかし、Controlsコレクションも共有されているため、元のControlsコレクションへの変更はすべてクローンに伝播されます。また、コントロールは状態(スタイル、イベントなど)を維持するためにもっと多くの隠れた参照を使用するため、MemberwiseCloneは非常に危険です。

コントロールをテンプレートの種類として再利用する唯一の方法は、新しいコントロール階層を作成するInstantiateInメソッドを持つテンプレート(ITemplate)を実際に使用することです。私はこれを行うリピータのようなコントロールを見ることをお勧めします。

+1

hm ...これは私が期待したものです。私は既にテンプレートを使ってコントロールを開発していますが、実際には、上記のコントロールはリピータコントロールをラップするコントロールのコンテキストで使用されます。簡単に言えば、ユーザは、内部的にリピータをラップするParentControlのコントロール "MyCustomCtrl"を一度定義します。したがって、リピーターのItemTemplateを処理する際には、MyCustomCtrlをコピーして、各RepeaterItem(基本的には行)にアタッチする必要があります。だから私は機能をコピーする必要があります。 – Juri

関連する問題