2009-05-13 9 views
1

いいえ、内部/外部のオブジェクトを更新する

これはおそらくC#の設計によるものか、間違った方法で行っているかもしれません。

下記のコードをご覧ください。私はそれをコピーしてコンソールアプリケーションに貼り付けて、それを実行して私が何を話しているのか見ることができます。

using System; 

namespace ConsoleTest 
{ 
    class Program 
    { 
     static void Main() 
     { 
      var o1 = new oObject 
          { 
           Name = "Before Method" 
          }; 

      var o1b = new oObjectBad 
      { 
       Name = "Before Method" 
      }; 

      Console.WriteLine("Object Bad 1 Before: " + o1b.Name); 
      oObjectBad o2b = GetNewObjectBad(o1b); 
      Console.WriteLine("Object Bad 1 After: " + o1b.Name); 
      Console.WriteLine("Object Bad 2 After: " + o2b.Name); 


      Console.WriteLine(string.Empty); 

      Console.WriteLine("Object 1 Before: " + o1.Name); 
      oObject o2 = GetNewObject(o1); 
      Console.WriteLine("Object 1 After: " + o1.Name); 
      Console.WriteLine("Object 2 After: " + o2.Name); 

      Console.ReadLine(); 
     } 

     public static oObject GetNewObject(oObject o) 
     { 
      oObject newObject = new oObject(o); 

      newObject.Name = "Changed in Method"; 
      return newObject; 
     } 

     public static oObjectBad GetNewObjectBad(oObjectBad o) 
     { 
      o.Name = "Changed in Method"; 
      return o; 
     } 
    } 

    class oObject 
    { 
     public oObject() 
     { 
     } 

     public oObject(oObject o) 
     { 
      Name = o.Name; 
     } 

     public string Name { get; set; } 
    } 

    class oObjectBad 
    { 
     public string Name { get; set; } 
    } 
} 

ここではわかりません。

私はメソッドにオブジェクトを渡し、オブジェクトプロパティ "名前"を更新します。メソッドの外にある元のオブジェクトを更新します。

これを回避する方法は、オブジェクトのクローンを作成してクローンを更新してからクローンを返すように(コードで示すように)他のオブジェクトを作成することでした。

これは問題です: オブジェクトを渡し、そのオブジェクトのプロパティを更新する簡単な方法がありますので、元のオブジェクトを更新することなくこのようなことができます。

using System; 

namespace ConsoleTest 
{ 
    class Program 
    { 
     static void Main() 
     { 
      var o1 = new oObject 
          { 
           Name = "Before Method" 
          }; 



      Console.WriteLine("Object 1 Before: " + o1.Name); 
      oObject o2 = GetNewObjectBad(o1); 
      Console.WriteLine("Object 1 After: " + o1.Name); 
      Console.WriteLine("Object 2 (New Object) After: " + o2.Name); 

      Console.ReadLine(); 
     } 

     public static oObject GetNewObjectBad(oObject o) 
     { 
      o.Name = "Changed in Method"; 
      return o; 
     } 
    } 

    class oObject 
    { 
     public string Name { get; set; } 
    } 
} 

これが混乱している場合は、私がよりよく説明できるかどうかを確認します。

編集: 私がこれをやっている理由は、データベース内のオブジェクトを複製する必要があり、複製されたオブジェクトに2つのプロパティを変更する必要があるためです。私は元のオブジェクトのIDと他のデータ処理のための新しいオブジェクトを使用します。

ありがとうございます!

答えて

2

参照渡しと値渡しを調べて、ローカルコンテキストで名前を変更する必要があるが、元の名前では変更しない理由を調べるのに時間を費やすことになります。私はあなたにいくつかの設計上の欠陥があるかもしれないという疑いがあります。問題をもう一度見直して、別のアプローチで解決策を開発できるかどうかを確認します。

+0

わかりました。私はこれとは別の方法でアプローチできるかどうかを調べるためにいくつかの調査を行うつもりです。クローンオブジェクトで作業し、後で他のデータを処理する必要がありました。私は間違った道を踏み出して、より固い原則を調べると思います。 – CodeLikeBeaker

0

.NETでは、すべてのオブジェクトはValueTypeから降りていない限り参照型です。通常、オブジェクトのインスタンス変数を直接変更することは望ましくありません。インスタンス変数をプライベートにしてからプライベートデータを操作するメソッドを追加すると、より多くの制御が可能になります。

http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx ValueTypeの死亡者のリスト。

1

なぜメソッド内のオブジェクトを変更し、そのデータを呼び出しメソッドに反映させたくないのでしょうか?あなたができることの1つは、変更を追跡するためのコードを実装し、元のオブジェクトを元のデータで返すメソッドをクラスに与えることです。

他の人が言っているように、これは値型対参照型の問題です。実際にオブジェクトが変更されないようにしたい場合は、型を構造体に変更することができます。私はそれが答えであると言っているわけではありません、私はあなたのクラスの構造を知っている問題についての情報を得た。