web-dev-qa-db-ja.com

ベストOOP C#での実践:オブジェクトをパラメーターとして渡すVSオブジェクトの新しいインスタンスを作成する

まず、オブジェクトをパラメータとして渡す方が、クラスを使用して別のオブジェクトを再度作成するよりもはるかに優れているかどうかを知りたいです。次に、それぞれの長所と短所を教えてください。

次に例を示します。

public class ClassWithTheObject
{

TheObject obj = new TheObject();

// Somewhere around the code
PassTheObjectHere anotherObj = new PassTheObjectHere(obj);

}

または、TheObjectクラス内でクラスPassTheObjectHereを宣言するだけですか? ClassWithTheObjectクラスとPassTheObjectHereクラスの両方がTheObjectクラスを使用する場合です。

最後の質問です。オブジェクトを何度も渡すと、プログラムに悪影響を及ぼしますか?

教えてください。

6
arvicxyz

あなたの質問はいくつかの誤解を示していると思います:

オブジェクトをパラメーターとして渡す

コンストラクタPassTheObjectHereで新しいインスタンスを直接作成する場合、obj内で以前に作成したPassTheObjectHereの値/状態を使用していないことは明らかです。その場合、objをパラメータとしてPassTheObjectHereに渡すことはほとんど役に立ちません。実際、このような場合、通常、TheObjecthasのメンバー変数があるかどうかを確認します。これにより、静的クラスの候補になる可能性があります(ただし、誤解しないでください。静的クラスを使用すると、デザインが多少改善されることはありません)。

一方、PassTheObjectHereneedsのコンストラクターが以前に作成されたobjの値/状態が適切に機能する場合、コンストラクターを持つことは明らかに間違っていますこのような。

 PassTheObjectHere()
 {
      var obj = new TheObject();

      // ... do something which expects having obj
      // ... some values provided by the caller
 }

(私はこれが明白であることを望みます)。

オブジェクトを何度も渡すと、プログラムに悪影響を与える可能性がありますか?

これは「多すぎる」の問題ではありません。オブジェクトを正確に約1000回渡すことができます。これは問題ありませんが、1回は間違っている場合は問題があります。たとえば、objをコンストラクタに渡し、コンストラクタがobjの状態を、呼び出し側が予期しない方法で変更した場合(「副作用」と呼ばれます)

  PassTheObjectHere(TheObject obj)
  {
       // ... use methods/properties/values of obj 
       // ... for this constructor

       // and finally
       obj.MakeValuesInvalid();
  }

そしてあなたは発信者が次のようなことをします

public class ClassWithTheObject
{

   TheObject obj = new TheObject();
   obj.Initialize()
   PassTheObjectHere anotherObj = new PassTheObjectHere(obj);
   obj.MethodWhichExpectsObjToBeValid();
}

次に、プログラムにバグがあります。それからあなたを守るために主に以下の選択肢があります:

  1. コンストラクター内で「obj」を変更しないことにより、副作用を回避します
  2. 「obj」を変更する必要がある場合は、コンストラクタ内で事前にコピーを作成してください。
  3. TheObjectに、objの内部状態の変更を可能にするメソッドを追加しないでください(「不変性」と呼ばれます)

番号3は1と同じコードになりますが、PassTheObjectHereが変更される可能性がある場合に、後で意図しない副作用が発生するのを防ぐための追加の保護があります。

3
Doc Brown

それよりも少し複雑です。

まず、トレードオフを理解します。元のオブジェクトへの参照ではなく、オブジェクトのコピー(基本的には「値渡し」のセマンティクス)を渡す場合、パフォーマンスに影響が出ます。そのヒットが正当化されるかどうかは、ソフトウェアの機能要件によって異なります。

第2に、渡されたオブジェクトをインプレースで変更したり、コピーしてからオブジェクトに渡したりするのではなく、参照によってオブジェクトを受け入れるメソッドを記述することは意味的に意味があります新しいオブジェクトを返す方法。

var modified object = ReturnANewObjectFrom(theOriginalObject);

この方法で新しいオブジェクトを作成して返すときは、immutability。を利用しています。不変性が意味をなす場合はどこでも、これは意味があります。不変オブジェクトとデータ構造を利用するプログラムは、特に並行アプリケーション(通常は別々のスレッドまたは別々のコアで同時に複数の処理を実行するアプリケーション)を作成する場合に、より簡単に推論できます。

4
Robert Harvey

それは本当にあなたが扱っているコンテキストに依存すると思います。あなたの例では、TheObjectインスタンスをPassTheObjectHereコンストラクターに送信しています。この方法で、PassTheObjectHereインスタンス内で以前の初期化されたデータを使用していることがわかります。したがって、ClassWithTheObjectがTheObjectインスタンスの会話状態を共有する場合は、問題ありません。それは私が思うことです

1
Enrique Olvera