Clear()方法也清除其他变量

时间:2015-04-07 06:43:38

标签: c#

这是我的代码摘录

List<int> Ids = new List<int>();
var transModelIds = db.TableName.ToList();
var statModelIds = db.TableName1.ToList();
foreach (var user in metaData){

    foreach(var s in someData){
    Ids.Clear();
    Ids = s.Type.Equals(<Condition>) ? transModelIds : statModelIds;
...
    }
}

someData 循环

的第一次迭代之后发生了什么

执行Ids.Clear()时,Ids,transModelIds,statModelIds都将被清除

为什么吗

但如果我把Ids.Clear()放在for循环上面它会起作用:

Ids.Clear();
foreach(var s in someData){<...Code...>}

代码工作正常

3 个答案:

答案 0 :(得分:3)

让我们来看看在这个循环foreach(var s in someData)将被执行多次的情况下会发生什么。

在第一次迭代中,您正在清除Ids,然后您正在分配(基于某些条件)Ids = transModelIdsIds = statModelIds

由于List<T>引用类型 - 在这种情况下,您不会复制这些列表内容会回到Ids,如您所料,但您创建指向transModelIdsstatModelIds的其他参考

在循环的下一次迭代中,您再次清除Ids,但从现在开始引用transModelIdsstatModelIds - 您只是清除这些列表。

答案 1 :(得分:2)

问题在于List&lt; T&gt;是一种参考类型。如果你编码:

Ids = s.Type.Equals(<Condition>) ? transModelIds : statModelIds;

您不复制列表,但将引用Ids指向相同的列表。

要解决它:

List<int> Ids = new List<int>();
var transModelIds = db.TableName.ToList();
var statModelIds = db.TableName1.ToList();
foreach (var user in metaData){

    foreach(var s in someData){
        Ids.Clear();
        Ids.AddRange(s.Type.Equals(<Condition>) ? transModelIds : statModelIds);
        /*... don't set the reference to the list but add the items from the source to your destination */
    }
}

另外,如果只在这个范围内需要它,你也可以在内循环中创建一个新的列表(因为Jon的评论已经建议我们在没有完整工作代码的情况下无法提供帮助):

var transModelIds = db.TableName.ToList();
var statModelIds = db.TableName1.ToList();
foreach (var user in metaData){

    foreach(var s in someData){
        List<int> ids = new List<int>();
        ids.AddRange(s.Type.Equals(<Condition>) ? transModelIds : statModelIds);
        /*... don't set the reference to the list but add the items from the source to your destination */
    }
}

你可以问自己的另一个问题是:

  

我是否需要临时名单?

在这种情况下,只需像你一样设置对列表的引用,但不要清除它。

修改

外部范围:

var transModelIds = db.TableName.ToList();
var statModelIds = db.TableName1.ToList();
List<int> ids = null;
foreach (var user in metaData){

    foreach(var s in someData){
        ids = s.Type.Equals(<Condition>) ? transModelIds : statModelIds;
        /*... additional code but don't modify the lists (clear or remove single items, etc...) ...*/
    }
}

内部范围:

var transModelIds = db.TableName.ToList();
var statModelIds = db.TableName1.ToList();
foreach (var user in metaData){

    foreach(var s in someData){
        List<int> ids = s.Type.Equals(<Condition>) ? transModelIds : statModelIds;
        /*... additional code but don't modify the lists (clear or remove single items, etc...) ...*/
    }
}

答案 2 :(得分:2)

您正在将transModelIds和statModelIds分配给Ids列表。清除Ids列表后,您还将清除分配给它的所有列表。请看下面的代码:

        List<int> list1 = new List<int>();
        List<int> list2 = new List<int>();

        list1.Add(1);
        list1.Add(2);
        list1.Add(3);
        list1.Add(4);
        list1.Add(5);

        list2 = list1;

        list2.Clear();

        Console.WriteLine(list1.Count + "  " + list2.Count);

        Console.ReadLine();

当您清除两个列表时,它将显示“0 0”。