Why list show strange behaviour? - c#

Work on Vs2010 EF,C#.
Have two list(oLisTranItem,oListTaxItem) ,need to copy one list properties values in another list ,then I need to work on new list.Problem is after copy content element one list to another list any type of changes impact on both list ,why this happen ,I just change on list but changes occur in both list
Please check my bellow syntax.
List<TransactionItem> oLisTranItem = new List<TransactionItem>();
List<TransactionItem> oListTaxItem = new List<TransactionItem>();
oLisTranItem = _TransactionItem;
oListTaxItem = _TransactionItemTax;
TransactionItem tmpItem = new TransactionItem();
tmpItem = oLisTranItem.Where(item => item.QuotationDetailID == quotationDetailID && item.Action != Entity.ActionMode.Delete && item.IsDeleted == false).FirstOrDefault();
if (tmpItem.IsNotNull())
{
tmpItem.Action = Entity.ActionMode.Add;
oListTaxItem.Add(tmpItem);
}
else
{
_TransactionItemTax = new List<TransactionItem>();
}
int nCounter = 5;
foreach (TransactionItem item in oListTaxItem)
{
if (item.QuotationTaxID ==0)
{
nCounter = nCounter + 1;
item.QuotationTaxID = nCounter;
}
}
Please help me to identify why this problem aries,how to solve this problem.
If have any query please ask,Thanks in advanced.

TransactionItem is probably a class, right? And not a struct.
Every type that's a class is, by default, a reference type. That means what you have in the lists are not the real values of the transaction items, but references (think C++ pointers) to those values. So when you copy data from one list to the other, you're just copying references.
You need to clone the items from one list to another. Give your class a method to clone instances, and use that method to copy items from one list to another.

Related

c# collections and re-numbering not working as expected

Hi i'm trying to setup simple test data.
I simply want to take a collection which is smallish and make it bigger by add itself multiple times.
After I;ve added them together i want to re-number the property LineNumber
so that there are no duplicates and that it goes in order. 1,2,3,4....
no matter what i try it doesn't seem to work and i cant see the mistake.
var sampleTemplateLine = dataContext.TemplateFileLines.ToList();
*//tired this doesnt work either*
//List<TemplateFileLine> lineRange = new List<TemplateFileLine>();
//lineRange.AddRange(sampleTemplateLine);
//lineRange.AddRange(sampleTemplateLine);
//lineRange.AddRange(sampleTemplateLine);
//lineRange.AddRange(sampleTemplateLine);
var allProducts = sampleTemplateLine
.Concat(sampleTemplateLine)
.Concat(sampleTemplateLine)
.Concat(sampleTemplateLine)
.ToList();
int i = 1;
foreach (var item in allProducts)
{
item.LineNumber = i;
i++;
}
this doesnt seem to work either
//re-number the line number
var total = allProducts.Count();
for (int i =0; i < total; i++)
{
allProducts[i].LineNumber = i+1;
}
PROBLEM: below RETURN 4 when i'm expecting 1
var itemthing = allProducts.Where(x => x.LineNumber == 17312).ToList();
You are adding the same objects multiple times. You wold have to add new objects or clone the ones you have.
The problem is they are pointing the same object. So if you change a property it changes all the pointed objects at the same
You can use Clone method if it exist, if not you can create your own Clone method like in this question.

Assigning to List to another List previous list automatically changes

I have two lists. When I assign List1 to List2 and I update List1, List2 automatically updates too. List2 shouldn't update. Why does this happen?
Here is my code:
public List<TrialBalance> TBal { get; set; }
public List<TrialBalance> PrevTBal { get; private set; }
if (this.PrevTBal == null)
{
this.PrevTBal = this.TBal;
}
for (int x = 0; x < this.TBal.Count; x++)
{
this.TBal[x].Balance = this.TBal[x].Balance + adjustments;
}
You are only assigning the references, not creating a copy of either the list or the items in the list.
You should create a new list and add all the items to it.
this.PrevTBal = new List<TrialBalance>(this.TBal.Select(b => clone(b));
When you assign a List<T>, you're copying the handle to the actual list in memory, which means the same list instance is being referenced by both variables.
In order to avoid this, you'd need to clone the list itself. In this case, that likely means needing to do two things - first, make a way to clone TrialBalance, then clone the list too:
// This assumes a TrialBalance.Clone() method which returns a new TrialBalance copy
this.PrevTBal = this.TBal.Select(tb => tb.Clone()).ToList();
Replace
if (this.PrevTBal == null)
{
this.PrevTBal = this.TBal;
}
by:
if (this.PrevTBal == null)
{
this.PrevTBal = this.TBal.ToList();
}
This way you're actually creating a copy of it instead of just refering it.

List<List> confusion

snippets of my code
List<List<optionsSort>> stocks = new List<List<optionsSort>>();
optionsSort tempStock1 = new optionsSort();
List<optionsSort> stock = new List<optionsSort>();
then some code,
for (int j = 1; j < optionsSt.Count; j++)
{
if (optionsSt[j].isin == optionsSt[j - 1].isin)
{
tempStock1.name = optionsSt[j].name;
tempStock1.date = optionsSt[j].date;
tempStock1.strike = optionsSt[j].strike;
tempStock1.size = optionsSt[j].size;
tempStock1.isin = optionsSt[j].isin;
tempStock1.callPut = optionsSt[j].callPut;
stock.Add(tempStock1);
}
else
{
stocks.Add(stock);
k = k + 1;
stock.Clear();
tempStock1.name = optionsSt[j].name;
tempStock1.date = optionsSt[j].date;
tempStock1.strike = optionsSt[j].strike;
tempStock1.size = optionsSt[j].size;
tempStock1.isin = optionsSt[j].isin;
tempStock1.callPut = optionsSt[j].callPut;
stock.Add(tempStock1);
}
}//endfor
Basicly, im going through a large list to sort elements into groups, a new List name stocks.
now the problem is, when I add to stocks all elements contained in the list stock and then clear stock on the next line to start again, I delete all the elements I have stored in stocks.
Any Ideas. Do I have to index stocks like stocks[i].Add(stock) so each block of similar stocks is an element in stocks.
Thanks for any help.
The problem is that List<T> objects, like all classes in .NET, are reference types. That means that every time you add stock to stocks you aren't adding a new list, you are only adding a reference to the same list in memory. So when you later call Clear, that is reflected both in your variable stock and in all other references in stocks.
You can resolve this by making a shallow copy of stock every time you add it to stocks:
stocks.Add(stock.ToList());
You're not creating a new list, you're using one list, and filling it and clearing it repeatedly. Since your outer list contains only one list, repeated multiple times, that list will have the same contents in every instance. That is, when you clear your list, you can no longer access the old contents, even if you try to access them from inside the outer list.
What you need to do is to change this line:
stock.Clear();
To this:
stock = new List<optionsSort>();
That is what you really meant. :)

How can i differentiate items in list in c#

I have one listitem and i am adding this listitem to a list multiple times with one property difference...
i.e listitem have DateOfService property..k...
then i am adding first item to list... it's fine
and i am changing DateOfService property and adding again...
but the previous added item DateOfService also changeing....
how can i overcome this problem...
sampleCode
if (bills[index].FrequencyId == Convert.ToInt32(Frequency.Daily))
{
for (int day = 0; day < remainedDays; day++)
{
bills[index].DateOfService = DateTime.Now.Date.AddDays(day).Date;
remainedBills.Add(bills[index]);
}
}
Hi i did this also but no use...
if (bills[index].FrequencyId == Convert.ToInt32(Frequency.Daily))
{
AdmissionEntryVo objAdmissionEntryVo = null;
for (int day = 0; day < remainedDays; day++)
{
objAdmissionEntryVo = new AdmissionEntryVo();
objAdmissionEntryVo = bills[index];
objAdmissionEntryVo.DateOfService = DateTime.Now.Date.AddDays(day).Date;
remainedBills.Add(objAdmissionEntryVo);
}
}
They're all the same object, you're not adding multiple ones. The only way to fix what you're talking about is to create new instances each time you add.
i am changing DateOfService property and adding again... but the
previous added item DateOfService also changeing
That is because you are adding an object reference to the list, and your objects in the list are pointing to the same reference, so when you are changing an item you are seeing the effect in the others. You need to create a new instance of your object and then modify its property and add it to the list.
Seems it relates to the "Preference and Primitive data type".
Since all of those objects are just the same object, so you keep adding the same object to your list.
My advice is to learn and distinguish "Preference and Primitive data types" before you continue. ;)
Cheers.
Hi all i've copied all properties to another listitem by writing extention method and added...
it's working fine...
Here is extention method
public static void CopyPropertiesTo<T>(this T source, T dest)
{
var plist = from prop in typeof(T).GetProperties() where prop.CanRead && prop.CanWrite select prop;
foreach (PropertyInfo prop in plist)
{
prop.SetValue(dest, prop.GetValue(source, null), null);
}
}

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

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

Categories