2010-12-02 9 views
0

私は昨日、メソッドに取り組んでいて、奇妙なことに遭遇しました。ここでは、コードのバージョンが間違っています:基本的に問題は、OrderByがBar.PopulateListメソッドが持続しません。メソッドにオブジェクトを渡して、そのオブジェクトに対してextendstionメソッドを呼び出す


class Foo 
{ 
    List MyObjects; 

    public void PopulateMyObjects() 
    { 
     //Items are added to my list but the OrderBy is not persisting. 
     Bar.PopulateList(MyObjects); 
    } 
} 

class Bar 
{ 
    public static int PopulateList(List theList) 
    { 
     foreach(var in WebSerbiceCall) 
     { 
      theList.Add(var); 
     } 
     // the OrderBy call only sorts 'theList' in the context of this method. 
     // When I return from this method theList has been populated but the Ordering has 
     // reverted back to the order that the items were added to the list. 
     theList.OrderBy(obj => obj.ID); 
     return theList.Count; 
    } 
} 

今私は、コードを更新してすべての作品下記のとおり、REFキーワードを追加した場合: 例えばパブリック静的int PopulateList(refリストをリスト) とBar.PopulateList(ref MyObjects);

誰でも私を啓発できますか?オブジェクトは常にrefによって渡されたと思った? OrderByが拡張メソッドであることは事実ですか?ここでの問題はOrderByコールが実際にしないことです

return theList.OrderBy(obj => obj.ID).Count; 

(私は、について説明を追加するつもりだったが、@jaredParがそれを説明しています)

答えて

4

おかげで、Cian

+0

私はあまりにも思ったので、私はしようとしました:theList = thisList.OrderBy(obj => obj.ID).ToList();下のMatthewに言及されているように、それはどちらもうまくいきませんでした。また、refキーワードを追加するのはなぜですか? – CianM

+0

@CianM 'theList'が' out'または 'ref'パラメータでないとまだ動作しません。それがなければ、メソッド内の参照のコピーを変更するだけです。 – JaredPar

+0

ありがとう!私は今理解しています、これで混乱している人のために、私は美しい写真で素晴らしい記事を見つけました:http://rapidapplicationdevelopment.blogspot.com/2007/01/parameter-passing-in-c.html – CianM

1

てみてくださいいかなる方法でもtheListを突然変異させる。代わりに、注文された新しいIEnumerable<object>が返されます。したがって、メソッド外の呼び出しの影響を見ることはできません。単にオブジェクトを変更しないだけです。

OrderByメソッドを使用すると、新しい値が作成されます。したがって、呼び出し元関数がこの新しい値を認識するようにするには、何らかの方法で返す必要があります。最も一般的な場所は戻り値またはref/out paramです。

+0

順序付けられた列挙型は、ソートされていないリストと同じ要素数を持っていませんか? – dtb

+0

OrderByの上にコードがあります:theList.Add(var);だから私はそれが仮定できるとは思わない。 – jwwishart

+0

しかし、OrderByは要素を追加または削除しないので、 'theList.OrderBy(obj => obj.ID).Count()'は 'theList.Count'と等しくなければなりません。 – dtb

1

C#は引数を値で渡します。参照型の値は、そのメモリの場所へのポインタです。あなたは結果を代入していない

theList.OrderBy(obj => obj.ID); 

theList = thisList.OrderBy(obj => obj.ID).ToList(); 
+0

こんにちは、これは私がorginallyも考えたものですが、それでも動作しませんでした。 – CianM

0

refキーワードを使用しない場合、渡されるパラメータは同じオブジェクトへの新しい参照です。それはある意味では「参照渡し」ですが、少し違って考える必要があります。

その他の回答が正しい場合、OrderByは実行されず、代わりに順序付きコレクションが返されます。しかし、パラメータを結果に設定した場合、基礎となるオブジェクト自体を変更するのではなく、パラメータ(参照)の値を新しいコレクションを指すように変更します。例えば、

theList = thisList.OrderBy(obj => obj.ID).ToList(); 

それは、注文をtheList

を取り、その後、新しいリストを作成します。次に、リストへの参照であるtheListの値が、新しく作成された(順序付けられた)リストを指すように変更されます。このメソッドの外部で作成された元の参照は、依然として元の順序付けられていないリストを指しています。

.ToList()に電話するたびに、実際に新しいリストが作成されるためです。 refキーワードを使用すると、同じリストへの新しい参照を作成するのではなく、参照を含む実際の変数をリストに渡します。

+0

ありがとうございます。それは本当に簡潔な説明です。 – CianM

+0

@CianM歓声は私のためにそれを投票すること自由に感じる! –

関連する問題