We are performing a migration and we are supposed to log the final report for the same. To achieve the same, I have a class which has multiple properties that holds List of Ids(string) such as All the Ids involved in Migration, All the Ids which are Migrated etc. While doing the same what I came across was that my previous assignment was getting updated when I performed a RemoveAll on a variable that holds all the List of Ids, to better understand, PFB an example:
public class Report {
public IdsInfo AllIds {get; set;}
public IdsInfo MigratedIds {get; set;}
public IdsInfo FailedIds {get; set;}
}
public class IdsInfo {
public int Count{get; set;}
public List<string> Ids {get; set;}
public IdsInfo(List<string> ids) {
Count = ids.Count;
Ids = ids;
}
}
//An example of the Method that does the Migration
public Report Migrate(string criteria) {
Report report = new Report();
//Assume below is a DB Call
List<string> allIds = db.getData(criteria).Select(x=>x.id).toList();//Assume Count = 1000
report.AllIds = new IdsInfo(allIds);
//Assume below is a DB Call to check whether Ids are already migrated
List<string> migratedIds = db.getData(x=>allIds.contains(x)).Select(x=>x.id).toList();//Assume Count = 300
allIds.RemoveAll(x=>migratedIds.contains(x));
report.MigratedIds = new IdsInfo(migratedIds);
return report;
}
What I was expecting =>
Report.AllIds.Count = 1000
Report.AllIds.Ids= {1000}//List
Report.MigratedIds.Count = 300
Report.AllIds.Ids= {300}//List
What actually happened =>
Report.AllIds.Count = 1000
Report.AllIds.Ids= {300}//List
Report.MigratedIds.Count = 300
Report.AllIds.Ids= {300}//List
I understand that Pass By Reference is what is causing this behavior but I would like to understand the reason behind this. My questions are as follows:
- Since I am creating a new instance of the Class IdsInfo shouldn't it avoid Pass By Reference?
- If Ans for 1 is no, then why is it that only the Ids List is updated and has 300 and the Count remains as is?
- How to avoid this? I understand that I can use FindAll instead of RemoveAll and assign the values to a new variable, but what if I want to reuse the same variable as shown.