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.
Related
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.
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.
I am new to OOP and C# so have what is potentially a noob question.
Looking at classes all the code I see requires the object names to be hardcoded. Say for example we don't know how many Customers a user will enter and what their names are. So how does that work with creating instances of a class?
Is it the case that you would only create one class of customer as a data type (with methods as required) and store them in say a list? Or can a class hold multiple instances of an object but create them and name them dynamically in relation to user input?
I've not quite got my head around how a class works with holding records in memory etc.
If you will iterate throught the objects in some moment I'd use a List.
As mentioned by #wazz you should store them in a list, like so:
List<Customer> customers = new List<Customer>();
Then you can start working with the list, adding new instances, removing etc.
You can check more information at the docs.
Note that a class is a type. You can think of it as template used to create objects (also called instances of this class). So, you can have many different objects of the same class.
You can differentiate between different objects of the same class by assigning them to different variables:
Customer a = new Customer { Name = "customer a" };
Customer b = new Customer { Name = "customer b" };
This has its limits, of course, as you do not want to declare one thousand variables when you have one thousand customers!
Here, collections come into play.
Store the customers in a collection. There are many different collection types. Probably the 2 most popular are List<T> and Dictionary<TKey, TValue>.
List<T> where T is a type (Customer in your case):
List<Customer> customers = new List<Customer>();
Customer c = new Customer { Name = "My first customer" };
customers.Add(c);
// You can re-use the same variable for another customer.
c = new Customer { Name = "My second customer" };
customers.Add(c);
// Or skip the temporary variable alltoghther.
customers.Add(new Customer { Name = "My third customer" });
The customer in the list can be accessed through a zero-based index
Customer c = list[5]; // Get the 6th customer
Lists can also be enumerated:
foreach (Customer cust in customers) {
Console.WriteLine(cust.Name);
}
Dictionary<TKey, TValue>: dictionaries allow you to lookup a customer by a key, e.g. a customer number.
Dictionary<string, Customer> customers = new Dictionary<string, Customer>();
Customer c = new Customer { Id = "C1", Name = "My first customer" };
customers.Add(c.Id, c); // The Id is used as key, the customer object as value.
Then you can get it back with
Customer c = customers["C1"];
This throws an exception if the supplied key is not existing. To avoid an exception you can write:
string id = "XX";
if (customers.TryGetValue(id, out Customer cust)) {
Console.WriteLine(cust.Name);
} else {
Console.WriteLine($"Customer '{id}' not found");
}
To help you understand a class first.
A class is a blueprint of what the data will look like. If you were to build, a house for example, you would first make the blueprints. Those prints could be used to make many houses that look that same. The differences in those houses vary in areas such as color, wood, brick, or vinyl, and if is has carpet or not. This is just an example but let's make this house into a class (blueprint) and then let's make several of those houses into actual individual objects; finally let's reference all of those in the same location (using a list).
First let's decide what our house options are, the things that set them apart. It's color, exterior, and with or without carpet. Here we will make color a string (text) for simplicity, the exterior as an enum ( so the options are hard coded), and the carpet or not a bool (true or false).
First let's make the enum since it is separate than a class but used within a class.
public enum Exterior { Brick, Vinyl, Wood }
Now let's make the class (the blueprint).
public class House
{
public string Color { get; set; }
public Exterior Exterior { get; set; }
public bool HasCarpet { get; set; }
}
Now that we have the blue print let's actually make some houses. When we make them we need to have a way to locate them in memory so we assign them to a variable. Let's pretend we are in a console app and this is the first few lines of the main method.
var house1 = new House();
var house2 = new House();
var house3 = new House();
Now we have 3 individual houses in memory and can get to any of them by referencing house1, house2, or house3. However, these houses are still built identical and unfortunately have no color (since the string Color is empty), are default to Brick (since the first enum is Brick), and have no carpet (since HasCarpet defaults to false).
We can fix this by referencing each house object reference and assigning these values like so...
house1.Color = "Red";
house1.Exterior = Exterior.Wood;
We could have given the classes a constructor that required these values as parameters to start with or we can do it a simpler way inline (thanks to the power of C# syntax).
var house1 = new House()
{
Color = "Red",
Exterior = Exterior.Wood
};
We could also give it carpet but since this house isn't going to have any and it defaults to false I've left it out.
Ok, so let's say we have all 3 houses built via our blueprint. Let's now store them together in a List. First we need to make the List into an object and reference that also.
var houses = new List<House>();
Now let's add the houses to the list.
houses.Add(house1);
houses.Add(house2);
houses.Add(house3);
Now houses is a reference to all of our house objects. If we want to get to a house in the list we could use an index (starting at 0) and get that location in the list. So let's say that house2 needs to have carpet but we want to use the list now to reference it. Note: There are quite a few ways to reference the items in a list, this one is elementary.
houses[1].HasCarpet = true;
I did this on my phone, hopefully there are no errors. My intentions are to clearly answer your question and educate and help you better understand classes.
Most likely, you would use an IEnumerable<Customer>. A Customer class in real life is related with a database.
When dealing with databases, Linq comes to mind which would use an IQueryable<Customer> (inherited from IEnumerable). As need arises you would also use other collection types like List<Customer>, Dictionary<...> etc
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.
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.