Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

list.add seems to be adding a reference to the original object?

Tags:

c#

list

I have created a couple custom classes (NTDropDown and NTBaseFreight) which I use to store data that I retrieve from a DB. I initialize a List of NTBaseFreight and 2 lists for NTDropDown.

I can successfully use List.Add to add freights to the freights list, but as I debug the code, my 2 dropdown lists contain only 1 NTDropDown, which always has the same values as NTDropDown (I'm assuming this is a referencing problem, but what am I doing wrong)?

To give an example, on the second row, if the carrier and carrier_label were "001", "MyTruckingCompany" and I put a break on the if statement for frt_carriers, both frt_carriers and frt_modes would contain only 1 item in their list, with the values "001", "MyTruckingCompany"...the same values in NTDropDown.

Code:

List<NTDropDown> frt_carriers = new List<NTDropDown>();
List<NTDropDown> frt_modes = new List<NTDropDown>();
List<NTBaseFreight> freights = new List<NTBaseFreight>();
NTDropDown tempDropDown = new NTDropDown();
NTBaseFreight tempFreight = new NTBaseFreight();

//....Code to grab data from the DB...removed

while (myReader.Read())
{
    tempFreight = readBaseFreight((IDataRecord)myReader);

    //check if the carrier and mode are in the dropdown list (add them if not)
    tempDropDown.value = tempFreight.carrier;
    tempDropDown.label = tempFreight.carrier_label;
    if (!frt_carriers.Contains(tempDropDown)) frt_carriers.Add(tempDropDown);

    tempDropDown.value = tempFreight.mode;
    tempDropDown.label = tempFreight.mode_label;
    if (!frt_modes.Contains(tempDropDown)) frt_modes.Add(tempDropDown);

    //Add the freight to the list
    freights.Add(tempFreight);
}
like image 691
Irfan jamal Avatar asked Nov 07 '12 18:11

Irfan jamal


People also ask

Why does adding a new value to list <> overwrite previous values in the list <>?

Essentially, you're setting a Tag's name to the first value in tagList and adding it to the collection, then you're changing that same Tag's name to the second value in tagList and adding it again to the collection. Your collection of Tags contains several references to the same Tag object!

What method is used to add items to a list object?

One of those methods is .append() , you can add items to the end of an existing list object. You can also use . append() in a for loop to populate lists programmatically.

Is ArrayList reference type in C#?

In fact the reference variable is passed by value, but behaves as if passed by reference. Consider var arr = new ArrayList(); The above statement first creates an ArrayList object and a reference is assigned to arr. (This is similar for any Class as class are reference type).

How do I copy a list in C#?

To clone a list, we can use a copy constructor, which is a special constructor to initialize a new instance of the List<T> class with a copy of the existing list. Assuming there are no mutable objects in the list, the copy constructor performs a shallow copy.


2 Answers

Yes, a list of reference types is actually just a list of references.

You have to create a new instance for each object that you want to store in the list.

Also, the Contains method compares references, so two objects containing the same data are not considered to be equal. Look for a value in the properties of the objects in the list.

if (!frt_carriers.Any(c => c.label == tempFreight.carrier_label)) {
  NTDropDown tempDropDown = new NTDropDown {
    value = tempFreight.carrier,
    label = tempFreight.carrier_label
  };
  frt_carriers.Add(tempDropDown);
}
like image 164
Guffa Avatar answered Nov 15 '22 16:11

Guffa


tempDropDown is the same object throughout the whole loop. You will need to create a new instance of it if you want to add more than one.

I'm having a hard time trying to figure out what exactly your'e trying to do with adding that tempDropDown the the list.

like image 28
hometoast Avatar answered Nov 15 '22 16:11

hometoast