C#のプロトタイプモデル(ディープコピー、浅いコピー)

プロトタイプモデルでは、新しいオブジェクトを作成する場合、重複したオブジェクトを作成するために使用されますが、オーバーヘッドが比較的大きい場合や、オブジェクトの現在の状態を保持したい、我々はプロトタイプモデルを使用することができます。

プロトタイピング

パブリック 抽象 クラスベース
{ 
    // なぜなら文字列の特殊な性質のために、私たちはStringBuilderを使用してこのデモ
    公共のStringBuilderに名前が{ GETSET ;}
     公共の int型年齢{ GETSET ;} 

    パブリックベース()
    { 
        // シミュレートし、それは、オブジェクトを作成するのにかかりますオーバーヘッド 
        のThread.sleep(1000年); 
    } 

    公共ベース(文字列名、int型の年齢)
    { 
        この .NAME = 新しい新規のStringBuilder(名前);
         この .Age = 年齢;
         //シミュレーションオブジェクトはオーバーヘッドに費やさ作成さ 
        のThread.sleep(1000年); 
    } 
    
    // ディープコピー
    パブリック 抽象ベースクローン();
     // 浅いコピー
    パブリック 抽象ベースMClone(); 
}

次にペロンは、基本を継承するクラスを作成してコピーし、2つのメソッドを実装します

// それは深いコピーのシリアル化を行うのであれば、、Serializableをラベル遊ぶ
[Serializableを]
 パブリック クラスパーソン:基本
{ 
    公共者() ベース()
    { 

    } 
    公共者(文字列名、int型の年齢)ベースを(名前、年齢)
    { 

    } 
    ///  <まとめ> 
    /// ディープコピー
     ///  </要約> 
    ///  <戻る>を新しいPersonオブジェクトを返す</戻り> 
    パブリック オーバーライドベースのクローン()
    { 
        // 作成メモリストリーム 
        MemoryStreamをミリ秒=新しい新規のMemoryStream();
         //はバイナリオブジェクト・シーケンスを作成する 
        にBinaryFormatter BF = 新しい新;にBinaryFormatter()
         // ストリームメモリ内の現在のオブジェクトのシリアル化は、MS書き込み 
        bf.Serialize(MS、これを);
         // 設定ストリームリード位置 
        ms.Position = 0 ;
         // デシリアライズオブジェクトはオブジェクト流れ
        戻り bf.Deserialize(MS)をAS 人; 
    } 

    ///  <まとめ> 
    /// 浅いコピー
     ///  </要約> 
    ///  <戻り値> </戻り値> 
    公共 オーバーライドベースMClone()=>
         // シャローコピー
        この .MemberwiseClone()などの人; 
}

すべての毎回の最初のMainメソッドの呼び出しは、我々は新しいPersonオブジェクトを作成します

静的 ボイドメイン(文字列[]引数)
{ 
    // 用于计时 
    ストップウォッチストップウォッチ= 新しいストップウォッチ()。
    stopwatch.Start(); 

    人物P = 新しい人物(" A "、2 8 )。
    人物P2 = 新しい人("A "28 ); 
    人物P3 = 新しい人("A "、2 8 )。

    stopwatch.Stop(); 
    Console.WriteLineを(" 耗时:" +stopwatch.Elapsed); 
    Console.ReadKey(); 
}

結果:

あなたは多くのオーバーヘッドを作成する場合、オブジェクトが表示されている場合、それらが効率的に作成されるたびに非常に低くなります

次に、我々は重複したオブジェクトを作成するために、プロトタイプモデルを使用し、MClone()シャローコピーを呼び出します

静的 ボイドメイン(文字列[]引数)
{ 
    // クロッキングのために 
    ストップウォッチストップウォッチ= 新しい新しいザ・ストップウォッチ(); 
    stopwatch.Start(); 
    
    人P = 新しい新規人物(" A "10 ); 
    人物P1 = p.MClone()AS ;人
    人P2 = p.MClone()AS パーソン; 

    // レコードの名前値、通じ直後の閲覧ウィンドウ 
    のStringBuilder NAME2 = p2.Name; 
    StringBuilderのNAME1 = p1.Name; 



    stopwatch.Stop(); 
    Console.WriteLineを(" 耗时:" + stopwatch.Elapsed)。
    Console.ReadKey(); 
}

Console.ReadKey()では、設定したブレークポイントで、実行するプログラム、入力の右下隅にデバッグウィンドウ>>インスタント、リアルタイムウィンドウを開く*&入力NAME1、*&、ビュー名1とname2のメモリアドレスを入力してくださいNAME2

我々は、参照NAME1とNAME2メモリアドレスはp2.Nameとp1.Nameには同一の参照ポイントであることを示し、同じであることができます。オブジェクトへの参照ですので、プロパティのタイプのために、簡易コピーを達成するために、すべての属性参照が同じオブジェクトを指すようになります、それは限りName属性を変更するためのオブジェクトがあるとして、他のオブジェクトのNameプロパティが変更されると言うことです。

営業成績を見てください

オブジェクトを作成するための最初の時間は、その後、非常に高速であるプロトタイプによってコピーされ、オーバーヘッドの多くを必要とだけのために見つけることができます。

次は深いコピーを見て

静的 ボイドメイン(文字列[]引数)
{ 
    // クロッキングのために 
    ストップウォッチストップウォッチ= 新しい新しいザ・ストップウォッチ(); 
    stopwatch.Start(); 
    
    人P = 新しい新規人物(" A "10 ); 
    人物P1 = p.Clone()AS ;人
    人P2 = p.Clone()AS パーソン; 

    // レコードの名前値、通じ直後の閲覧ウィンドウ 
    のStringBuilder NAME2 = p2.Name; 
    StringBuilderのNAME1 = p1.Name; 



    stopwatch.Stop(); 
    Console.WriteLineを(" 耗时:" + stopwatch.Elapsed)。
    Console.ReadKey(); 
}

今、同じ操作を実行し、メモリアドレスを見て

メモリ内のP1およびP2名アドレスは同じではありませんが、見つけることができ、オブジェクトのすべての非静的プロパティディープコピーを説明することであるコピーを持って、あなたが発生した場合は再作成する参照型であろう、代わりにコピーオブジェクトへの参照。

最後に、我々は、営業成績を見て

 

おすすめ

転載: www.cnblogs.com/ckka/p/11368572.html