3

最初に簡単な例を挙げて私の要点を確認します (単なる通常のリスト)。

    private void button1_Click(object sender, EventArgs e)
    {
        List<string> Olle = new List<string>();

        Olle.Add("Niklas");
        Olle.Add("Peter");
        Olle.Add("Tobias");

        RemoveFirst(Olle);

        MessageBox.Show(Olle.Count().ToString()); 

    }
    private void RemoveFirst(List<string> O)
    {
        O.Remove(O.First());  
    }

リストは参照によるものであるため、メッセージ ボックスには 2 be が表示されます。

IQueryable または IEnumerable スネア (Linq から Sql) のリストに対して同じ動作を期待していましたが、驚いたことに値変数になりました。すなわち。メソッドを渡して戻ってきた後、メソッドはリストをフィルタリングすることでした! 以下の例によると:

    private void foo(int therecord)
    {
      var FooList = DataContext.MyTable.Where
                    (l => l.ID == therecord).OrderBy(l => l.FirstName).ToList();

       //Lets say the result is 15 records. 
        MessageBox.Show(FooList.Count().ToString());

       //filter method
        RemoveDoubletItems(FooList);


       //Still 15 records - why? It should pass by refernce right? 
       //and show 14 - But its not !    

        MessageBox.Show(FooList.Count().ToString());

    }

    private void RemoveDoubletItems(List<MyTable> FooList)
    {
        var remList = new List<MyTable>();

           remList.Add(FooList.First());//Just an example

           FooList = FooList.Except(remList).ToList();

       //Shows 14 
        MessageBox.Show(FooList.Count().ToString())
    }

どうしてこれなの?

4

2 に答える 2

3

FooList.Except(remList).ToList();新しいリストを作成します。ソース コレクションは変更しません。

メソッドには、インスタンスを指すfooローカル変数があります。FooListList<MyTable>

同じ参照を渡し、RemoveDoubledItemsそれを別のローカルFooList変数に割り当てています。

次に、List<MyTable>( を使用して) 新規作成し、その新しいリストを指すようにExcept().ToList()ローカル変数を変更します。FooListただし、FooListfromfooメソッドはまだ初期リストを指しています! そのため、Count15 が返されます。

于 2013-08-21T09:31:17.920 に答える