2011-07-14 7 views
3

.Netでは、値を返すメソッドを連鎖するか、voidを使用して連鎖させることができます。そのうちの1つは「正しい方法」ですか?.NETでメソッドを連鎖させる正しい方法は何ですか

だから、この場合

1)

Foo myFoo = new Foo(); 
myfoo.Bars = 
    myBars.DoSomethingCool(x) 
    .DoSomethingElse(y) 
    .AndSomethingElse(z); 

public static IList<IBar> DoSomethingCool(this IList<IBar> source, object x) 
{ 
    IList<IBar> result = //some fn(source) 
    return result; 
} 

、すべての3つの拡張メソッドがIListの(myFoo.Bars用タイプ)

を返却する必要があると言うことができるか、それも可能性があり

2)

myBars.DoSomethingCool(x) 
.DoSomethingElse(y) 
.AndSomethingElse(z); 

public static void DoSomethingCool(this IList<IBar> source, object x) 
{ 
    //Modify source 
    source = //some fn(source) 
    //Don't return anything 
} 
01として書き込ま

この場合、拡張メソッドはvoidを返しますが、入ってくるソースオブジェクトに対して作業を行いますか?

UPDATEサイモンは、2)はコンパイルされないとの彼の答えで正しいです。ここではそれは書き換えることができる方法である:

DoSomethingCool(myBars) 
.DoSomethingElse(myBars) 
.AndSomethingElse(myBars); 

myBarsは、各メソッドの呼び出し内で変更されるだろうとの方法はvoidを返すことになります。

+3

よりもはるかに進歩していたコードのデバッグに難しく、修正し、維持することができます。 –

+0

デバッグ、修正、メンテナンスの難しさを理解しているかどうかはわかりません。チェーニングを別々の行に置くと、いずれかのステートメントにブレークポイントを設定できます。連鎖することで意図を表現するのが容易になり、保守を簡単にすることが難しくないように見えます。 – John

+0

2番目の例はコンパイルされません。 DoSomethingElse()はDoSomethingCoolの戻り値に対して呼び出されます。これは無効です。 – sisve

答えて

0

1)が勝ちます。 Simonは2)はコンパイルしないと答えましたが、彼はコメントとしてそれを行いました。私は彼に答えるための信用を賭けることはできません。 2)のための更新された解決策は、静的型付けされた言語でそれをしたいと思う理由を考えることができない副作用としてすべてを行います。

チェーニングのデバッグに関する問題点は何かを考慮する必要がありますが、私はチェーニングがフィルタリングの際に特に役立つことがわかります。

mybars.FilterByHasHappyHour()は、メソッドの連鎖

BigGiantUtilityClass.GetBarsWithHappyHours(myBars) 
0

どちらの場合でも、拡張メソッドを使用してオブジェクトを返し、そのオブジェクトをチェーン内の次のメソッドへの入力として使用しています。 2番目の例は、Fluent Interfaceに近いです(しかしそれほどではありません)。私はあなたの2つの例では、重要な差異は変異性の一つだと思います。元の入力を変更する(2番目の例)かしないか(最初の例) 「正しい」答えは、状況や状況によって異なります。

+0

これは疑問です。オリジナルの入力を変更しても問題ないですか、または副作用による操作を悪いものにしていますか? – John

+0

私は混乱を避けるために私が個人的に離れているかもしれませんが、この方法で拡張メソッドを変更することは必然的に「悪いこと」であることはわかりません - 少なくとも、オブジェクトを「変更」のようなものに変更するメソッドの名前を付けます。 .. "または" Modify ... "を選択します。 ほとんどのLinq拡張メソッドは、イテレータ上で動作し、元のものを変更するのではなく新しいシーケンスを提供します。最小の共通分母(イテレータ)を操作して返すことで、Linq拡張は、最も幅広い状況と対象オブジェクトに適応することができます。 – daveaglick

+0

しかし、拡張メソッドは実際に他のメソッドと違いはないことに注意してください。最初のパラメータは明示的ではなく暗黙的です。暗黙のことは、オブジェクトが操作対象外にあるため、このメソッドは他のものよりアクセスできないということです。元のオブジェクトが変更可能でない場合、チェーン内のメソッドはそれを変更することはできません。つまり、元のオブジェクトのインタフェースが適切に設計されている限り、いずれのアプローチでもカプセル化を破る危険性はありません。 – daveaglick

関連する問題