How to properly replace objects in an array - C# - c#

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.

Related

New list<string> not acting indepently

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.

Another class property call from base class list

I have a two class properdata and pprosecnddata both classes having property
I want to access product property from properdata class list object. How is it possible,below is my sample code
pupilc class ProperData
{
public string code{get;set;}
public List<ProSecndData>Secnd{get;set;}
}
public class ProSecndData
{
public string product{get;set;}
}
I am trying to call property like that
class Program
{
static void Main(string[] args)
{
ProperData.Secnd.Product = "Hello";
}
}
you cannot directly access property of Secnd as it is a list
you need to iterate or select the index of the List<Secnd>
you must initialize Secnd first and Secnd should have items in the list
properData.Secnd = new List<ProSecndData>();
so it can be access via
foreach(var second in properData.Secnd)
{
second.product = "hello";
}
//or
for(var i = 0; i < proderData.Secnd.Count(); i++)
{
properData.Secnd[i].product = "hello";
}
//or
var index = //0-length of list;
properData.Secnd[index].product = "hello";
if you want to have items first then add first on your Secnd List
properData.Secnd = new List<ProSecndData>();
properData.Secnd.Add(new ProSecndData{ product = "hello"});
then you now can iterate the list by using methods above
You are trying to access list as a single object, which is not possible.
you need to create single instance of your list class and then you can add string in that single instance.
properData.Secnd = new List<ProSecndData>();
ProSecndData proSecndData = new ProSecndData();
proSecndData.product = "Hello";
properData.Secnd.Add(proSecndData);
Actually I know the answer already, you have not created a constructor to initialise your List.
I'm guessing you get a object null ref error?
Create the constructor to initialise your list and it should be fine.
But in future, please post the error message (not the whole stack, just the actual error) as well as all the code required to repeat the issue. Otherwise you run the risk of getting your question deleted
(It should be deleted anyway because it could be considered a "what is a null ref err?" question).
Also you are accessing an item in a list like the list is that item (should be more like: ProperData.Secnd.elementAt(0).product, please also note the capitalisation of 'product' in the model vs your code.

List elements are dependant from each other

For some reason, elements in my list(Maps = new List<CollisionTiles>[]) are dependant from each other. This list contains information about collision tiles in my game. The problem is, when I set list elements in Map list to Maps[Something], Maps list is changing too, whenever I do anything with Map after assignation.
if (mapClass.Maps[3].Count != 0)
{
mapClass.ClearMap(); // CollisionTiles.Clear(); BackGroundTiles.Clear();
mapClass.CollisionTiles = mapClass.Maps[3];
mapClass.BackgroudTiles = mapClass.SpriteMaps[3];
}
if (mapClass.Maps[3].Count == 0)
{
mapClass.GenerateCustomMap(64, 10, 8, 3, false);
}
Really difficult to say from the code you've posted but based on your description you might be copying a "reference" to a collection when you intended to copy the collection itself.
For example, let's say to have a list called a and you try to make a another list called b like this:
var a = new List<string>();
var b = a;
What the above code is actually doing is making a and b a "reference" to the same list.
In other words, if you then did something like this:
b.Add("item");
Now both of the "lists" called a and b will have the same items in them. That's because they are not actually different lists, they are the same list with two "pointers".
There's a couple of different ways you can correctly copy of a list in C#. One way is to pass the list into the constructor like this:
var a = new List<string>();
a.Add("item");
var b = new List<string>(a);
This will give you two separate lists with that both have an item in them. However, now when you modify either of those lists they won't change together.
A popular (more modern) alternative approach for the code above can be done by using System.Linq namespace.
var a = new List<string>();
a.Add("item");
var b = a.ToList();
I hope that helps.
You are setting mapClass.CollisionTiles to reference to the original List.
Therefore, any modifications to the mapClass.CollisionTiles changes the original List as well. The same goes for BackgroundTiles.
To correct this, create new List objects when assigning them to the mapClass:
if (mapClass.Maps[3].Count != 0)
{
mapClass.ClearMap(); // CollisionTiles.Clear(); BackGroundTiles.Clear();
mapClass.CollisionTiles = new List<CollisionTiles>(mapClass.Maps[3]);
mapClass.BackgroudTiles = new List<BackgroudTiles>(mapClass.SpriteMaps[3]);
}
else // this is the only other option from the above if
{
mapClass.GenerateCustomMap(64, 10, 8, 3, false);
}
Please note, I have left the misspelling of BackgroudTiles, please correct as necessary.

Declare Instance of Class with Dynamic Name

So I have created a Class called SnakeItem, I want to create a new instance of the snake item when the snake grows, they follow a naming convention of snake_Piece_[NUMBER]. There is already snake_Piece_0 and I want to declare a new instance in the code. I'm not sure how to put it...
SnakeItem snake_Piece_0;
public game_Window()
{
InitializeComponent();
snake_Piece_0 = new SnakeItem(Resource1.Black, 0, 0);
}
Then in this function, I want to create it. (after snake_length++:) I need to name to increment so it follows the snake_length Variable. i.e. if snake_length = 1 then it will create a piece with the name snake_Piece_1.
private void fruit_Collision()
{
if (snake_Piece_0.Top == Fruit_Item.Top && snake_Piece_0.Left == Fruit_Item.Left)
{
snake_Length++;
}
}
I'm not sure what I can say if it's not possible I would have to declare all 400 snake pieces beforehand which is what I'm trying to avoid.
This is a common thing that beginners do - trying to dynamically create new variables with new names. I tried to do this too, until I learned about Lists.
Lists are objects that can store a variable number of objects. Here is how you can create an empty list of SnakeItem:
List<SnakeItem> snakeItems = new List<SnakeItem>();
You can add, access, and delete items in the list. Here are some examples:
snakeItems.Add(new SnakeItem(Resource1.Black, 0, 0)); // add a new item to the list
snakeItems[0] // access the first item in the list. 0 is the first, 1 is the second, etc.
snakeItems.RemoveAt(0) // remove the first item of the list
Basically, whenever you want to create a new "variable name", just Add a new item to the list:
if (snakeItems[0].Top == Fruit_Item.Top && snakeItems[0].Left == Fruit_Item.Left)
{
snakeItems.Add(...);
}
As you can see, snake_Length is not needed any more! You can access how many snake items there are using .Count. Replace all the snake_Length with snakeItems.Count.
Learn more about lists here.

ViewModel returns same values for all 500+ records to the view

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.

Categories

Resources