2015-04-07 57 views
-2

这是我的代码摘录Clear()方法清除其它变量也

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...>} 

的代码工作正常

+2

请显示一个简短但完整的程序来展示问题。目前我们没有足够的信息来帮助你。 –

+2

请注意,[标签:模型视图控制器]是针对有关*模式*的问题;如果您的问题涉及ASP.NET实现,请使用[tag:asp.net-mvc]标签。 –

+0

@TiesonT。这并不是说这个问题与任何类型的MVC,模式都没有任何关系。标签删除完全合适。 = D –

回答

2

问题是,列表< T>是一个引用类型。如果你的代码:

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 */ 
    } 
} 

然而,你可以问自己一个问题是:

我需要临时LIS t呢?

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

编辑

外部范围:

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...) ...*/ 
    } 
} 
+0

只是要清楚,它会产生多少差异? – Biswajeet

+1

@Biswajeet很多。实现取决于是否需要拥有一份列表副本(需要额外的内存),或仅仅是对这两个列表中的任何一个的引用......我将添加不将列表复制到答案的情况。 –

+0

非常感谢, 因为我们必须分配多次,addrange有时会产生重复(需要),所以我们保留了那个Ids.clear,然后添加了addRange。 – Biswajeet

3

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

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

由于List<T>参考类型 - 在这种情况下,你不是抄袭这些列表的内容回Ids正如你所期待的,但你创建指向transModelIdsstatModelIds另一个参考

而且在你再次清除Ids循环的下一次迭代,但因为现在是参考transModelIdsstatModelIds - 你只是清除这些列表。

2

你assinging transModelIds和statModelIds到IDS列表。一旦清除了ID列表,您也将清除分配给它的所有列表。看看下面的代码:

 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”。

+0

Gullie这帮我理解了这个参考问题,谢谢 – Biswajeet

+0

复制两个列表的数据的方法是遍历所有的元素源列表并将它们添加到第二个列表。按项目逐项。 –

+0

是通过使用Add()或AddRange()方法,得到它 – Biswajeet