如果我们先拿一个简单的例子来看看我的观点(只是一个普通的列表)
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())
}
为什么会这样?
答案 0 :(得分:6)
你在这里混淆了两件事。
不通过引用传递。实际上两个实例都指向相同的引用。
在第一个示例中,您正在修改相同的引用,以便在原始列表中看到更改,而在第二个示例中,您将在此处分配新引用
FooList = FooList.Except(remList).ToList();
这意味着现在FooList没有指向它之前指向的引用。因此,您没有看到原始列表中的影响。你可以看到你在做什么,如下图所示。
答案 1 :(得分:3)
FooList.Except(remList).ToList();
创建新列表 - 它不会修改源集合。
在foo
方法中,您有一个本地FooList
变量,该变量指向List<MyTable>
个实例。
您将相同的引用传递给RemoveDoubledItems
并将其分配给另一个本地FooList
变量。
然后,您正在创建新的List<MyTable>
(使用Except().ToList()
)并更改本地FooList
变量以指向该新列表。但是,来自FooList
方法的foo
仍然指向初始列表!这就是Count
返回15的原因。