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 是因为该列表是引用的!

我期望 IQueryable 或 IEnumerable 圈套(Linq to Sql)的列表具有相同的行为,但令我惊讶的是它变成了一个值变量,有人可以向我解释一下吗?IE。传递一个方法返回后,方法是过滤列表!根据下面的例子:

    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

7

你在这里混淆了两件事。

它不是通过引用传递的。实际上这两个实例都指向相同的引用。

在第一个示例中,您正在修改相同的引用,以便在原始列表中看到更改,而在第二个示例中,您在此处分配新的引用

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

这意味着现在 FooList 没有指向它之前指向的引用。因此,您在原始列表中看不到影响。您可以在下图中看到您在做什么。

在此处输入图像描述

于 2013-08-21T09:32:31.513 回答
3

FooList.Except(remList).ToList();创建新列表 - 它不会修改源集合。

foo方法中,您有局部FooList变量,它指向List<MyTable>实例。

您正在传递相同的引用RemoveDoubledItems并将其分配给另一个局部FooList变量。

然后,您正在创建新的List<MyTable>(使用Except().ToList())并更改局部FooList变量以指向该新列表。但是,FooListfromfoo方法仍然指向初始列表!这就是为什么Count返回 15。

于 2013-08-21T09:31:17.920 回答