2012-01-25 8 views
2

操作が同一であれば、例1では、オブジェクトへの参照が渡され、オブジェクトが操作されます。例2では、​​オブジェクトへの参照が渡され、オブジェクトが操作され、次に同じ参照が返されます。ref型を取るvoidメソッドとそれを操作するメソッドと同じオブジェクトに参照を返すメソッドとの間に違いはありますか?

static void Foo(SomeReferenceType t) 
{ 
    //Do something with t 
} 

static SomeReferenceType Foo(SomeReferenceType t) 
{ 
    //Do same thing with t 
    return t; 
} 

Bar bar = new Bar(); 

//Does this 
Foo(bar); 
//Do the same thing as this 
bar = Foo(bar); 
+0

あなたが産生されたILを見ていました両方の? – Oded

+0

私は最初の行が 'static void Foo(ref SomeReferenceType t)' – Douglas

+0

であると仮定します。ピアレビューア:私の編集リクエストを破棄してください。 – Douglas

答えて

3

後者は流暢なタイプのインターフェースで連鎖メソッドを可能にしますが、オブジェクトが操作されているという事実を隠すことができます。そのようにして渡されているオブジェクトを操作するのはあまり一般的ではありません。なぜなら、オブジェクトが変更されたときにメソッドのコンシューマーを混乱させるからです。あなたがすることは、オブジェクトをクローンし、それを操作し、操作されたクローンを返すことです。これにより、最初の参照のオブジェクトはそのままの状態になります。

前者では、消費者が変数を渡して「親愛なる方法は、この変数を取って、新しいメモリアドレスを指し示すなど、必要なことをしてください」と言っています。したがって、開発者は、渡された状態が操作される可能性があることを認識します。ところで

は、私はあなたがこれを読むべきだと思う:http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx

私は潜在的な開発者にインタビューするとき、私は参照することにより、その値によって参照と値の型を渡すことについて多くの質問をお願いします。私はこれを理解していない上級レベルの職位について開発者にインタビューしましたが、C#開発の基本であると思います。

0

一つの重要な概念の違いは、同じタイプの異なるオブジェクトのインスタンスが返されますがstringような不変オブジェクトを「操作」されている方法を実行するとき、それは場合、すなわちであることかもしれない - 各メソッドは、新しい異なるstringオブジェクトを返します。

もちろん、2番目の方法でメソッド呼び出しを連鎖できるインスタンスメソッド(または拡張メソッド)が用意されているので、返されたオブジェクトインスタンスの追加メソッドを呼び出すことができます。これにより、より流暢な対話が実現します。

SomeReferenceType result = obj.Foo() 
           .Bar() 
           .Baz() 
+0

@ KonradRudolph:私はあなたに従っているかわかりません - 私の例では、私は別の*オブジェクトが返された、同じではないと仮定しています。あなたが同じオブジェクトを返す場合、返された実際の参照は、実際のポインタ/参照が異なっていても、ヒープ上の正確に同じ位置を指すことになります。 – BrokenGlass

+0

私のコメントを無視...削除。 –

0

このケースでは、まったく同じことが行われます。

フォームのために、オブジェクトを返す関数ではなくvoid関数を選択します。なぜなら、関数がオブジェクトを返すと、後でコードを管理する人が、関数が新しいインスタンスを作成し、パラメータに渡されたオブジェクトを変更しないままにします。

0

私が見ることができる唯一の大きな違いは、オブジェクトを返す場合、実際には同じクラスの別のインスタンスを返すことができることです。しかし、あなたの例では、それらは機能的に同じです

1

これはまた、私には判読上の問題です。既に投稿されているその他の回答に加えて、SomeReferenceTypeを返すと、渡された元のインスタンスは変更されず、返されたインスタンス(別のオブジェクトである必要があります)に対して突然変異が行われることが示唆されます。私がこのコードを使って作業していたのであれば、元の著者は、元の型への参照を保存し、それが変更されないという事実を数えることができると示唆していたと思います。

方法の唯一の意図は、オブジェクトを変異させる場合には、それが修飾する方法とデータが一緒に封入されているので、それは、でSomeReferenceTypeクラスに定義されなければならないが:

class SomeReferenceType() 
{ 
    public void Foo() 
    { 
     // mutate instance here 
    } 
} 

SomeReferenceType a = new SomeReferenceType(); 
a.Foo(); 
関連する問題