How can i differentiate items in list in c# - 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);
}
}

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.

Iterate over custom list and Remove item from list conditionally in C#

I want to iterate over a custom list i.e. defined as:
List<CurrentCluster> _curClusters = new List<CurrentCluster>();
IEnumerator<CurrentCluster> _clusIterate = _curClusters.GetEnumerator();
while (_clusIterate.MoveNext())
{
// Error_01: Cannot implicitly convert CurrentCluster to Cluster
Cluster _curClus = _clusIterate.Current; // Cluster is base class while
// CurrentCluster is derived class
// Error_02: Does not contain a definition for GetClusterSize()
if (_curClus.GetClusterSize() == 0)
{
// Error_03: Remove(char) has some invalid arguments.
_clusIterate.ToString().ToList().Remove(_curClus);
}
}
while method GetClusterSize() is defined in class Cluster.cs as:
public int GetClusterSize()
{
return _clusterObjects.Count;
// _clusterObjects is a defined in this class as:
// List<EvoObject> _clusterObjects = new List<EvoObject>();
}
If the size of specific cluster is equal to zero in that cluster list (i.e. _curClusters then to remove that cluster from the list.
How can we iterate over a custom list and remove item from list conditionally?
How about just using List RemoveAll method and doing this?
_curClusters.RemoveAll(_curClus=>_curClus.GetClusterSize() == 0);
You should be able to use a for loop - you have to work backwards because otherwise you would be moving the elements and some would get skipped.
for (int n=_curClusters.Count; n>=0; n--)
{
if (_curClusters[n].GetClusterSize()==0)
{
_curClusters.RemoveAt(n);
}
}
Removing items from a collection using iteration is both advanced and obsolete technique. Use LINQ instead:
_curClusters = _curClusters.Where(c => c.GetClusterSize() > 0).ToList();
Now curClusters contains just "sized clusters", whatever that means.
If you insist to do it through iterations this is the way:
The catch is that you MUST NOT change a collection while iterating over its items. Instead, you can iterate and determine if an item needs to be deleted and mark it somehow - for instance you can add it to another list which contains only items to be deleted. After the first iteration over the original collection, start second one and remove the items from the original, like so:
var toBeRemoved = new List<CurrentCluster>();
foreach (var suspiciousCluster in _curCluseters)
{
if(suspiciousCluster.GetClusterSize() == 0)
{
toBeRemoved.Add(suspiciousCluster);
}
}
foreach (var voidCluser in toBeRemoved)
{
_curCluster.Remove(voidCluster);
}
Again, _curClusters contains just "sized clusters", whatever this might mean.
However I highly recommend the first approach.
I did not understand why you are going with that complexity ... simply you can achieve the goal by below code
List<CurrentCluster> _curClusters = new List<CurrentCluster>();
_curClusters.RemoveAll(i => i.GetClusterSize()== 0);
//OR
for (int i = 0; i < _curClusters.Count; )
{
//If you have some more logical checking with CurrentCluster
//before remove
if (_curClusters[i].GetClusterSize()== 0)
{
_curClusters.Remove(_curClusters[i]);
continue;
}
i++;
}

Why list show strange behaviour?

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.

Removing Item from List<DBTables> in C# [duplicate]

This question already has answers here:
What is the best way to modify a list in a 'foreach' loop?
(11 answers)
Closed 9 years ago.
I am currently working on a C# WPF project. I have a list which uses a class to store multiple values. The class is called DBTables and has the following inside:
class DBTables
{
public string selDatabase { get; set; }
public string selTable { get; set; }
}
I am creating a new instance of the list with the following code
List<DBTables> tableArr = new List<DBTables>();
I am adding new items to the List without any problems but the problem I am having is when it comes to removing an item from the list.
A an item is added to the list when a checkbox is selected the item is added and when the checkbox is unchecked the item needs to be removed. Each time the checkbox is checked two values are added using the following code:
private void addBackupArray(string table)
{
backupArr.Add(new DBTables
{
selDatabase = selectedDatabase,
selTable = table
});
}
When the check box is unchecked the values at the position need to be removed and I have sort of got it working but after it has removed the item it then displays the error 'InvalidOperationException, collection was modified; enumeration may not execute'.
Below is the code that I am currently using to remove the item from the list.
private void removeBackupArray(string table)
{
int i = 0;
foreach (DBTables tables in backupArr)
{
if (selectedDatabase == tables.selDatabase && table == tables.selTable)
{
backupArr.RemoveAt(i);
i = 0;
}
i++;
}
}
The code above iterates through the values in the list and based on an if statement of whether the two variables match the value found in the list it removes it at the current position of the counter i.
How can I get round this issue so I can remove the item without getting the error.
Thanks for any help you can provide.
Change the foreach to normal for loop will fix the issue:
for (int tablesIndex = 0; tablesIndex < backupArr.Count; tablesIndex++)
{
var tables = backupArr[tablesIndex];
if (selectedDatabase == tables.selDatabase && table == tables.selTable)
{
backupArr.RemoveAt(tablesIndex);
tablesIndex--;
}
}
Changed your foreach to a for loop. The foreach uses an enumerator to iterate over all of the objects in the List. You can't change the contents of the enumerator within the foreach or you'll get the error you see.
Give this a try instead
int i;
for (i = 0; i < backupArr.Count; i++)
{
DBTables tables = backupArr[i];
if (selectedDatabase == tables.selDatabase && table == tables.selTable)
{
break;
}
}
backupArr.RemoveAt(i);
A neater solution could be to use a linq like so:
DBTables tables = backupArr.Where(t => t.selDatabase == selectedDatabase && t.selTable == table).SingleOrDefault();
if (tables != null)
backupArr.Remove(tables);

iterating over a collection and removing ones I dont want

I have a problem with the following. I have a collection:
Collection<Vehicle> list = new Collection<Vehicle>();
code = 1,2,3, Description = "aaa"
code = 10,438,13, Description = "bbb"
code = 81,8623,362, Description = "ccc"
code = 163,4312,53, Description = "ddd"
...
But I only care about some of them.. The list I care about is here, i.e. codesCareAbout = "1|2|3|163|4312|53"
I need to iterate through the collection and either deleting the Vehicle I don't care about, or cherry picking into another list containing the Vehicles I care about?
Any suggestions?
Many thanks,
James
You can iterate your list backwards, and use RemoveAt using the for index to remove from the list:
for (int i = list.Count - 1; i >= 0; i--)
{
Foo item = list[i];
if (IsFoobar(item))
list.RemoveAt(i);
}
Counting backwards is required so that you don't mutate your index counting as you go, using a for loop is required because you cannot mutate a list being enumerated with an enumerator.
Alternatively, do as you suggested, populate into an empty list the stuff you want - however, usage depends on whether you need to modify the list you are given or can make a new list.
Assuming that Vehicule has Code (string) property and Description property (question is not clear !).
1/ Clone the list : var clone = list.ToList();
2/ Iterate and decide if current item is interesting :
foreach(var item in clone)
{
if (! IsInteresting(item))
list.Remove(item);
}
3/ IsInteresting could be, for example :
foreach(var code in item.Code.Split(','))
{
if (codesCareAbout.Split('|').Contains(code))
return true;
}
Filtering the list with linq produces the cleanest code:
var interestinglist = list.Where(v=> v.IsInteresting(v));
IsInteresting can be implemented as
codesIcareAbout.Intersect(v.Codes).Any();
this assumes both fields are collections rather than strings, but that is easily fixed with a call to string.Split().

Categories