参考类型参数和Linq

时间:2015-11-10 08:23:46

标签: c# linq

我将列表作为参数传递给方法。在Linq Where子句之后,列表值保持不变。

    void ChangeList(List<int> list)
    {
        list.Add(1);
        list.Add(2);
        list = list.Where(c => c > 1).ToList();
        list.Add(3); // List values: 2, 3
    }

    void Test()
    {
        var list = new List<int>();

        list.Add(0);

        this.ChangeList(list);

        // List values: 0, 1, 2
    }

可能,C#就像Linq查询中的函数编程一样。

导致此行为的原因是什么?为了避免任何意外错误,我想确切地知道导致这种情况的原因。

感谢您的帮助和指导。

2 个答案:

答案 0 :(得分:1)

你的问题不是LINQ,而是你的List参数是按值传递的,所以在你的外部代码中,你仍然拥有你传递的List的修改副本,但不是ToList方法创建的新副本在方法ChangeList内。

要获取ToList方法创建的新列表,您必须以这种方式通过引用传递参数:

  void ChangeList(ref List<int> list)

请记住,默认情况下,C#是按值传递的。

答案 1 :(得分:1)

ToList创建一个与原始列表无关的新列表。 Passing Reference-Type Parameters

  

引用类型的变量不直接包含其数据;它   包含对其数据的引用。传递引用类型时   参数值,可以更改指向的数据   引用,例如类成员的值。但是,你   不能改变引用本身的值;也就是说,你做不到   使用相同的引用为新类分配内存并拥有它   在街区外坚持。为此,请使用以下命令传递参数   引用或退出关键字。

您有三种选择:

不要使用LINQ

void ChangeList(List<int> list)
{
    list.Add(1);
    list.Add(2);
    for(int i = list.Count - 1; i >= 0; i--)
        if(list[i] <= 1) list.RemoveAt(i);
    list.Add(3); // List values: 2, 3
}

或从方法

返回列表
List<int> GetList(List<int> list)
{
    list.Add(1);
    list.Add(2);
    for(int i = list.Count - 1; i >= 0; i--)
        if(list[i] <= 1) list.RemoveAt(i);
    list.Add(3); // List values: 2, 3
    return list;
}
// ...
list = GetList(list);

或使用ref

void ChangeList(ref List<int> list)
{
    list.Add(1);
    list.Add(2);
    list = list.Where(c => c > 1).ToList();
    list.Add(3); // List values: 2, 3
}
// ...
this.ChangeList(ref list);