IQueryable 列表不是按引用传递的吗?(linq to sql)

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)列表会有同样的行为,但令我惊讶的是它变成了一个值变量,有人能解释一下吗?即在传递方法后回来,该方法需要过滤列表!根据以下示例:
    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())
    }

为什么会这样呢?
2个回答

7

你在这里混淆了两个概念。

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

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

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

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

是的,谢谢 - 我又可以呼吸了! :) 它正在创建一个新对象!当我使用 toList() 时。 - Niklas
谢谢提供电路图,解释得很清楚! - Niklas

3

FooList.Except(remList).ToList();创建了一个新的列表 - 它没有修改源集合。

foo方法中,您有一个本地的FooList变量,它指向List<MyTable>实例。

您将相同的引用传递给RemoveDoubledItems并将其分配给另一个本地FooList变量。

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


@Niklas FooList是一个局部变量,在你将它指向新的List<T>之后,它与来自foo方法的FooList没有任何关系。请查看我的更新答案。 - MarcinJuraszek
@marcinjuraszek 是正确的,你可以在这里查看... http://msdn.microsoft.com/zh-cn/library/bb300779.aspx - A.T.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接