为什么修改 collection 也会修改 foreach 中的前一个
Why modifying a collection also modifies the previous one in a foreach
基本上我的代码的目的如下:
我有 collection 个特工,有“Matricule”和“Temps Base”。有些特工只有一个“Temps Base”,他们只会在collection中出现一次,但有些特工有多个“Temps Base”,因此会出现多次。
如果代理只有一个“Temps Base”(用双精度表示),没问题。
如果他有多个,比如三个,我只想把它们加起来,只保留一个 object 但其中包含三个双打的总和。
这是我的 class:
public class AgentJournalier
{
public string Matricule { get; set; }
public double TempsBase{ get; set; }
}
我的 collection :
private ObservableCollection<AgentModel> _TousAgents;
public ObservableCollection<AgentModel> TousAgents
{
get
{
return _TousAgents;
}
set
{
if (value != _TousAgents)
{
_TousAgents = value;
RaisePropertyChanged(nameof(TousAgents));
}
}
}
private ObservableCollection<AgentModel> _AgentsContratEnCours;
public ObservableCollection<AgentModel> AgentsContratEnCours
{
get
{
return _AgentsContratEnCours;
}
set
{
if (value != _AgentsContratEnCours)
{
_AgentsContratEnCours = value;
RaisePropertyChanged(nameof(AgentsContratEnCours));
}
}
}
对于此测试,我的 Collection TousAgents 将包含 3 行:
Matricule : Bec - TempsBase : 100
Matricule : Bec - TempsBase : -25
Matricule : Bec - TempsBase : -10
我的代码:
foreach (AgentModel tsag in TousAgents)
{
if (AgentsContratEnCours.Any(p => p.Matricule == tsag.Matricule) == false)
{
AgentsContratEnCours.Add(tsag);
}
else
{
AgentModel AgentDejaDansLaListe = new AgentModel();
AgentDejaDansLaListe = AgentsContratEnCours.Where(x => x.Matricule == tsag.Matricule).FirstOrDefault();
AgentsContratEnCours.Remove(AgentsContratEnCours.Where(x => x.Matricule == tsag.Matricule).FirstOrDefault());
AgentDejaDansLaListe.TempsBase = AgentDejaDansLaListe.TempsBase + tsag.TempsBase;
AgentsContratEnCours.Add(AgentDejaDansLaListe);
}
}
foreach (AgentModel tsag in TousAgents)
{
Console.WriteLine($"Temps base : {tsag.TempsBase}");
}
foreach (AgentModel tsag in AgentsContratEnCours)
{
Console.WriteLine($"Temps base total : {tsag.TempsBase}");
}
考虑到一个代理人会在列表中出现 3 次,具有相同的“Matricule”但具有 3 个不同的“TempsBase”(例如:100、-10、-25),我想要的输出如下:
Output :
Temps base : 100
Temps base : -25
Temps base : -10
Temps base total : 65
但我实际得到的输出是这个:
Output :
Temps base : 65 <== Why ??
Temps base : -25
Temps base : -10
Temps base total : 65
显然,如果我第二次调用该方法,“Temps Base”会继续递减(因为它不再具有其原始值 100,而是新值:65):
Output :
Temps base : 30 <== Why ??
Temps base : -25
Temps base : -10
Temps base total : 30
我想了解为什么“TousAgents”中的第一个值发生变化。
我的目标是第一个 Collection 中的值永远不会改变,所以我创建了第二个:AgentsContratEnCours。
但是,当我更改 AgentsContratEnCours 中的值时,即使我没有手动为“TousAgents”分配任何内容,它也会在 TousAgents 中更改它。你能解释一下为什么吗?我该如何避免这种情况?
您对引用类型所做的有问题的假设导致您犯了这个错误。错误的假设在下面的代码中,你能发现吗?
AgentModel AgentDejaDansLaListe = new AgentModel();
AgentDejaDansLaListe = AgentsContratEnCours.Where(x => x.Matricule == tsag.Matricule).FirstOrDefault();
AgentDejaDansLaListe.TempsBase = AgentDejaDansLaListe.TempsBase + tsag.TempsBase;
让我解释一下。 AgentModel
是一种引用类型,这意味着如果您在 AgentModel
中更改其属性(Marticule 和 TempsBase),它们将在它的所有副本中更改。
在第一行你创建一个新的 AgentModel
命名为 AgentDejaDansLaListe
然后在第二行你把它扔掉(进入垃圾收集器)然后分配一个完全不同的引用给它。
在最后一行中,您修改了该对象的 TempsBase,这也更改了列表中该原始对象的 TempsBase,因为 AgentModel
是引用类型。
要解决此问题,请使用 AgentModel
的结构或在其中实施克隆。
基本上我的代码的目的如下: 我有 collection 个特工,有“Matricule”和“Temps Base”。有些特工只有一个“Temps Base”,他们只会在collection中出现一次,但有些特工有多个“Temps Base”,因此会出现多次。 如果代理只有一个“Temps Base”(用双精度表示),没问题。 如果他有多个,比如三个,我只想把它们加起来,只保留一个 object 但其中包含三个双打的总和。
这是我的 class:
public class AgentJournalier
{
public string Matricule { get; set; }
public double TempsBase{ get; set; }
}
我的 collection :
private ObservableCollection<AgentModel> _TousAgents;
public ObservableCollection<AgentModel> TousAgents
{
get
{
return _TousAgents;
}
set
{
if (value != _TousAgents)
{
_TousAgents = value;
RaisePropertyChanged(nameof(TousAgents));
}
}
}
private ObservableCollection<AgentModel> _AgentsContratEnCours;
public ObservableCollection<AgentModel> AgentsContratEnCours
{
get
{
return _AgentsContratEnCours;
}
set
{
if (value != _AgentsContratEnCours)
{
_AgentsContratEnCours = value;
RaisePropertyChanged(nameof(AgentsContratEnCours));
}
}
}
对于此测试,我的 Collection TousAgents 将包含 3 行:
Matricule : Bec - TempsBase : 100
Matricule : Bec - TempsBase : -25
Matricule : Bec - TempsBase : -10
我的代码:
foreach (AgentModel tsag in TousAgents)
{
if (AgentsContratEnCours.Any(p => p.Matricule == tsag.Matricule) == false)
{
AgentsContratEnCours.Add(tsag);
}
else
{
AgentModel AgentDejaDansLaListe = new AgentModel();
AgentDejaDansLaListe = AgentsContratEnCours.Where(x => x.Matricule == tsag.Matricule).FirstOrDefault();
AgentsContratEnCours.Remove(AgentsContratEnCours.Where(x => x.Matricule == tsag.Matricule).FirstOrDefault());
AgentDejaDansLaListe.TempsBase = AgentDejaDansLaListe.TempsBase + tsag.TempsBase;
AgentsContratEnCours.Add(AgentDejaDansLaListe);
}
}
foreach (AgentModel tsag in TousAgents)
{
Console.WriteLine($"Temps base : {tsag.TempsBase}");
}
foreach (AgentModel tsag in AgentsContratEnCours)
{
Console.WriteLine($"Temps base total : {tsag.TempsBase}");
}
考虑到一个代理人会在列表中出现 3 次,具有相同的“Matricule”但具有 3 个不同的“TempsBase”(例如:100、-10、-25),我想要的输出如下:
Output :
Temps base : 100
Temps base : -25
Temps base : -10
Temps base total : 65
但我实际得到的输出是这个:
Output :
Temps base : 65 <== Why ??
Temps base : -25
Temps base : -10
Temps base total : 65
显然,如果我第二次调用该方法,“Temps Base”会继续递减(因为它不再具有其原始值 100,而是新值:65):
Output :
Temps base : 30 <== Why ??
Temps base : -25
Temps base : -10
Temps base total : 30
我想了解为什么“TousAgents”中的第一个值发生变化。 我的目标是第一个 Collection 中的值永远不会改变,所以我创建了第二个:AgentsContratEnCours。 但是,当我更改 AgentsContratEnCours 中的值时,即使我没有手动为“TousAgents”分配任何内容,它也会在 TousAgents 中更改它。你能解释一下为什么吗?我该如何避免这种情况?
您对引用类型所做的有问题的假设导致您犯了这个错误。错误的假设在下面的代码中,你能发现吗?
AgentModel AgentDejaDansLaListe = new AgentModel();
AgentDejaDansLaListe = AgentsContratEnCours.Where(x => x.Matricule == tsag.Matricule).FirstOrDefault();
AgentDejaDansLaListe.TempsBase = AgentDejaDansLaListe.TempsBase + tsag.TempsBase;
让我解释一下。 AgentModel
是一种引用类型,这意味着如果您在 AgentModel
中更改其属性(Marticule 和 TempsBase),它们将在它的所有副本中更改。
在第一行你创建一个新的 AgentModel
命名为 AgentDejaDansLaListe
然后在第二行你把它扔掉(进入垃圾收集器)然后分配一个完全不同的引用给它。
在最后一行中,您修改了该对象的 TempsBase,这也更改了列表中该原始对象的 TempsBase,因为 AgentModel
是引用类型。
要解决此问题,请使用 AgentModel
的结构或在其中实施克隆。