I have same type of 2 object lists and first item of first list should be added specific times. Also every cycle i should increase the datetime value with AddSeconds(). This is my code below:
List<Logs> logList = new List<Logs>();
List<Logs> chartList = new List<Logs>();
for (int i = 0; i < specificValue; i++)
{
chartList.Add(logList[0]);
logList[0].Date = logList[0].Date.AddSeconds(1);
}
My purpose is creating chart data with change log so i have to add same value to chartList with specific time with incremental date value. But my problem this code creates a chartList with all the same value of the last loglist item. I found some solutions with using foreach but in that situation i have to use for loop.
When you call chartList.Add(logList[0]), you are adding a reference to the object, not creating a new object.
So on the next line, when you add 1 second to the object, you also add that 1 second to the object in chartList. In fact, all the objects in chartList are references to the exact same object.
You need to create a copy of the object when you add it to chartList.
Related
I have List<string> I am passing from model to control and back again. My initial problem was that when I use List.remove() to remove an item from the list<> it is somehow coming back when passing it back to the View.
I decided to create a new list<>, put the model.List<> values in it, clear the Model.List<>, and then put the values from the tmp List<> back in the Model.List<>.
However, when I clear the Model.List<> the tmp List<> values are being cleared as well.
if (!string.IsNullOrEmpty(model.removeDate))
{
model.multipleSingleDay_Date.Remove(model.removeDate);
List<string> tmpV = new List<string>();
tmpV = model.multipleSingleDay_Date;
model.multipleSingleDay_Date.Clear();
model.multipleSingleDay_Date = tmpV;
}
You are using a reference to the original list.
To make a new list, use a new List<string>(); and iterate through your original list to fill the new one. This can be done in several ways.
tmpV = model.multipleSingleDay_Date;
All the above line does is say "the reference the variable model.multipleSingleDay_Date has should be used in the tmpV variable".
Loop through the original list and add each value to the new list. Or copy the list, see comments below.
In a for loop, instead of declaring a new object and add it to my List, I just update the value of the old object and every time keep adding this old object to my List, why after a few loops all List elements become the same
foreach (vg_ts_VesselCashflow_CashFlow_Entity item in cashflow)
{
var result = new VslMonthlyCashflow_Record();
result.CapitalCost = item.CapitalCost;
result.CharterRevenue = item.CharterRevenue;
result.Date = item.Period;
result.DryDock = item.DryDock;
resultList.Add(result);
}
if (resultList != null)
return resultList;
//Compared with this:
var result = new VslMonthlyCashflow_Record();
foreach (vg_ts_VesselCashflow_CashFlow_Entity item in cashflow)
{
result.CapitalCost = item.CapitalCost;
result.CharterRevenue = item.CharterRevenue;
result.Date = item.Period;
result.DryDock = item.DryDock;
resultList.Add(result);
}
I expect my resultList to be updated but if I keep using the old object, when it loops 123 times, all elements in the List will be the same.
List#Add doesn't copy the object or anything like that, it just keeps a reference to the object you passed to it. In the second snippet, you keep adding the same object to the list multiple times. Each modification you perform on the object is visible through all the references pointing to it, including the local result variable and all the elements of the list.
I am new to using ViewModels, I have a new list here and am adding items to it by looping though a database table. The issue is that all the records that come back are identical using the same record over and over. What could be the issue and is this a good way to accomplish filling with data and Passing a ViewModel or is there a better way? Right now it returns about 500 records with the same data.
public class DimCustomersController : Controller
{
private AdventureWorks_MBDEV_DW2008Entities db = new AdventureWorks_MBDEV_DW2008Entities();
public ActionResult CustomersIndexVM()
{
List<DimCustomersIndexViewModel> CustomerList = new List<DimCustomersIndexViewModel>();
DimCustomersIndexViewModel CustomerItem = new DimCustomersIndexViewModel();
foreach (var m in db.DimCustomers.ToList())// cold do for loop up to count
{
CustomerItem.Title = m.Title;
CustomerItem.FirstName = m.FirstName;
CustomerItem.MiddleName = m.MiddleName;
CustomerItem.LastName = m.LastName;
CustomerItem.BirthDate = m.BirthDate;
CustomerItem.MaritalStatus = m.MaritalStatus;
CustomerItem.Suffix = m.Suffix;
CustomerItem.Gender = m.Gender;
CustomerItem.EmailAddress = m.EmailAddress;
CustomerItem.AddressLine1 = m.AddressLine1;
CustomerItem.AddressLine2 = m.AddressLine2;
CustomerItem.Phone = m.Phone;
//other columns go here
CustomerList.Add(CustomerItem);
}
return View("CustomersIndexVM", CustomerList);
}
This line needs to be inside the loop:
DimCustomersIndexViewModel CustomerItem = new DimCustomersIndexViewModel();
The reason is that you want a new view model for each customer, but instead you are currently creating only one view model and changing its properties. When you add it to the list, you are not adding a copy; you are adding the same view model you already added.
This code would work if DimCustomersIndexViewModel was a struct, because structs are just a bag of values that have no inherent identity and they are copied rather than referenced. (Technical comparison.) But it's a class (as it should be), with a unique identity, so you're adding a reference to the single view model into the list over and over. Customerlist[0] and CustomerList[1] and all the other items point to the same DimCustomersIndexViewModel object instance, whose properties are then overwritten and left equal to the very last customer.
By moving this line inside the loop, you are creating a separate DimCustomersIndexViewModel for each customer, each with its own set of properties, and CustomerList contains references to many different DimCustomersIndexViewModel object instances.
Once you have solid experience with this concept, a future step could be to use AutoMapper so that you don't have to maintain a list of all properties in your code here.
The problem is you add the same reference object during each iteration of your loop. That object never changes (you never new it up again), but you change the properties on the object. Then you add that object over and over. You need to new up that object each iteration of the loop.
The code below doing a simple thing. manipulate the API's raw data and bind it to the view model's property.
I fetch data from a web service and save it to a object named calljsonObject. This is the raw data. Then I do a foreach loop to select the selected data from the raw data, and save it to a object named tmpList, and at the last line, bind tmpList to the view model property named docList
SingleBoardListRawData calljsonObject = JsonConvert.DeserializeObject<SingleBoardListRawData>(callbackjsonstring);
ObservableCollection<SinglePostViewModel> tmpList = new ObservableCollection<SinglePostViewModel>();
SinglePostViewModel tmpPost = new SinglePostViewModel();
foreach (List<object> item in calljsonObject.data)
{
tmpPost.doc_id = (long)item[0];
tmpPost.doc_title = (string)item[1];
tmpPost.doc_author = (string)item[2];
tmpPost.repliesCount = (long)item[4];
tmpPost.doc_post_date = DateTime.Parse((string)item[5]);
tmpPost.OnTop = (long)item[6];
tmpPost.CoolPost = (long)item[7];
tmpPost.doc_update_date = DateTime.Parse((string)item[9]);
tmpPost.PicInDoc = (long)item[10];
tmpPost.reply_user_name = (string)item[11];
tmpPost.doc_brief = (string)item[13];
tmpList.Add(tmpPost);
}
this.docList = tmpList;
But the result is the tmpList full of the same data, which is the result of the last foreach manipulation. But I thought that I've re-assigned the tmpPost value, it seems every Add method will take place the previous one.
I don't want to new a object everytime I do a foreach loop, I think it cost a lot,
My Question is :
1. Why?
2. How to solve it?
You're adding a reference to the same object on each iteration, and overwriting the data within that object on each iteration. You need to create a new object on each iteration. Move this line:
SinglePostViewModel tmpPost = new SinglePostViewModel();
into the loop.
foreach (List<object> item in calljsonObject.data)
{
SinglePostViewModel tmpPost = new SinglePostViewModel();
tmpPost.doc_id = (long)item[0];
...
}
I don't want to new a object everytime I do a foreach loop, I think it cost a lot,
How do you expect to maintain the different values if you don't create that many objects? Where do you expect the data to live? And what evidence do you have for your performance concern?
It's very important that you understand how reference types and value types work. Please read my article on this topic and think about how that applies in your situation.
If we assume that SinglePostViewModel, then you are adding the same reference multiple times in the list. There is only one instance of the SinglePostViewModel - you are simply over-writing it each time, hence the fail.
I don't want to new a object everytime I do a foreach loop, I think it cost a lot
Unless you are talking 10s of millions of records, your concerns are very unlikely to be justified. The data needs to go somewhere, after all.
My Question is : 1. Why? 2. How to solve it?
because you only have one object that you keep over-writing
don't do that
I am trying to remove an object from an array and fill the slot with an object of the same type but with 0s for all the properties. But when I do this the values do not clear for some reason when I recalculate the array values.
Here is how I am clearing an object out and inserting a blank one in its place.
public void clearOutBox(int arraySlot)
{
itemsInbuildArray.Remove(itemsArray[arraySlot]);
itemsInbuildArray.Insert(arraySlot, blank);
itemInBuildPictureArray[arraySlot].ImageLocation = null;
statCalculation();
}
//one of the lines from the statCalculation method.
statsHealth.Text = (Convert.ToString(itemsInbuildArray.Sum(hp => hp.Health)));
public partial class Form1 : Form
{
List<Item> itemsArray = new List<Item>();
List<PictureBox> itemInBuildPictureArray = new List<PictureBox>();
List<ToolTip> itemInBuildTooltipArray = new List<ToolTip>();
List<Item> itemsInbuildArray = new List<Item>();
Item blank = new Item(); // this is one of several objects created here
}
I initialize the array with 6 of these blank items in it and there are no problems replacing a blank item with one with values but removing it is whats causing me issues.
Please excuse the more than likely noobish ways I'm doing this, I am just starting C# and doing this project as a learning experience. Any input is appreciated!
Why not just index it directly:
int index = 5;
array[index] = new Foobar(); // whatever your class is
That is going to change whatever is referenced in the 6th slot in your array.
I would avoid using a single reference called "blank" and putting it into multiple array slots unless you know you will never modify them. If they are reference types then modifying one of them would modify them all.