0

私は昨日メソッドに取り組んでいて、何か奇妙なことに遭遇しました。ここにコードのダムバージョンがあります。基本的に問題は、Bar.PopulateListメソッドに適用されたOrderByが持続しないことです。


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キーワードを追加すると、すべて機能します。たとえば、public static int PopulateList(ref List theList)およびBar.PopulateList(ref MyObjects);

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

ありがとう、Cian

4

5 に答える 5

4

ここでの問題は、OrderBy呼び出しが実際にはまったく変更theListされないことです。代わりに、IEnumerable<object>注文された new を返します。したがって、メソッドの外側で呼び出しの影響が見られないのはこのためです。単にオブジェクトを変更していないだけです。

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

public static int PopulateList(ref List<object> theList) {
  ...
  theList = theList.OrderBy(obj => obj.ID).ToList();
}
于 2010-12-02T00:25:41.123 に答える
1

試す:

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

(説明を追加するつもりでしたが、@jaredPar が説明してくれました)

于 2010-12-02T00:25:40.093 に答える
1

C# は引数を値で渡します。参照型の値がそのメモリ位置へのポインターであることだけです。あなたが抱えている問題は次の行です:

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

結果を割り当てていません:

theList = thisList.OrderBy(obj => obj.ID).ToList();
于 2010-12-02T00:26:16.273 に答える
1

Enumerable.OrderBy拡張メソッドは、 List<T>をインプレースで並べ替えません。リストの要素を並べ替えた順序で返す IEnumerable<T> を返します

List<T>.Sort メソッドを使用して、 List<T >をインプレースで並べ替えます。

于 2010-12-02T00:26:38.037 に答える
0

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

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

例えば、

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

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

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

于 2010-12-02T00:58:13.110 に答える