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);
}
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!
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.
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).
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.
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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With