Instantiating User Defined Object inside Another Object in C# - c#

I need some help with the way I am storing objects/data inside my application. I am creating an application that: creates a robot, assigns tasks to robot, displays the robot information with task time etc..
I have setup multiple different objects to be instantiated in Main when the program is run. Then the user will select a robot type from the list of types. I am having trouble passing the botType object into the Robot object. I am asking the user to select a botType 1-6 using int, then I would like the user selected int to define which botType should be applied to the Robot.
Because I am initializing the BotTypes in Main, then using a different method to CreateRobot(). I am having trouble passing the botType into the Robot object. I can pass the integer the user selects but this is not passing the botType into Robot like I am trying to complete..
Here are my classes/constructors being used:
public class Robot
{
//Store robot name
public string botName { get; set; }
//Store robot type
public BotType botType { get; set; }
//Store time to complete task
public int timeElapsed { get; set; }
public Robot(string BotName, BotType botType, int TimeElapsed)
{
this.botName = BotName;
this.botType = new BotType();
timeElapsed = TimeElapsed;
}
public class BotType
{
//Type of robot
public string TypeName { get; set; }
//Type of task represented by number
public int TaskType { get; set; }
//contructor to set values
public BotType (string typeName, int taskType)
{
TypeName = typeName;
TaskType = taskType;
}
Then my main method where the objects are being initialized but when I try to use them, I am unable to convert user defined int into BotType like I would like..
public class BotOMat
{
public static List<Robot> botList = new List<Robot>();
public static List<BotTask> botTaskMap = new List<BotTask>();
public static List<BotType> botTypeMap = new List<BotType>();
static void Main(string[] args)
{
//initalize bot types
BotType UNIPEDAL = new BotType("Unipedal", 1);
BotType BIPEDAL = new BotType("Bipedal", 2);
BotType QUADRUPEDAL = new BotType("Quadrupedal", 3);
BotType ARACHNID = new BotType("Arachnid", 4);
BotType RADIAL = new BotType("Radial", 5);
BotType AERONAUTICAL = new BotType("Aeronautical", 6);
//initialize bot tasks
BotTask DISHES = new BotTask("Do the dishes", 1000, 0);
BotTask SWEEP = new BotTask("Sweep the house", 3000, 0);
BotTask LAUNDRY = new BotTask("Do the laundry", 10000, 0);
BotTask RECYCLING = new BotTask("Take out the recycling", 4000, 0);
BotTask SAMMICH = new BotTask("Make a sammich", 7000, 0);
BotTask LAWN = new BotTask("Mow the lawn", 20000, 0);
BotTask RAKE = new BotTask("Rake the leaves", 18000, 0);
BotTask BATH = new BotTask("Give the dog a bath", 14500, 0);
BotTask BAKE = new BotTask("Bake some cookies", 8000, 0);
BotTask WASH = new BotTask("Wash the car", 20000, 0);
var botTaskMap = new List<BotTask> { DISHES, SWEEP, LAUNDRY, RECYCLING, SAMMICH, LAWN, RAKE, BATH, BAKE, WASH };
var botTypeMap = new List<BotType> { UNIPEDAL, BIPEDAL, QUADRUPEDAL, ARACHNID, RADIAL, AERONAUTICAL };
private static void createRobot()
{
//Get robot name, add to list saving multiple names.
Console.WriteLine("Enter robot name:");
string botName = Console.ReadLine();
//Get robot type
Console.WriteLine("Enter robot type: (number)");
int botType = Convert.ToInt32(Console.ReadLine());
//botType = botTypeMap[botType];
//boxing to convert int to BotType
//error handling
if (botType < 1 || botType > 6)
{
Console.WriteLine("Invalid input. Please enter number 1-6.");
//BotType.TaskType = 0;
}
//Add robot to the class storing robot information.
if (botType > 1 || botType < 6)
{
Robot aRobot = new Robot(botName, botType, 0);
botList.Add(aRobot);
aRobot.AssignBotTask();
aRobot.CompleteTask();
}
else
{
MainMenu();
}
}
I can either pass BotType into Robot as an Integer or receive an Arguement 2: cannot convert from int to BotOMat.BotType. Whenever I try to write any output using aRobot the console is writing using the protected variables which is not the desired output.
Should I be creating aRobot in the Robot class? I then need to assign BotTask(s) to the robot later on... I believe these use an Association type relationship but if the objects are not initialized in each class. I am unsure how to initiate; for example: a Unipedal Robot that does the Dishes.
I appreciate any help in advance. I tried to be as descriptive as possible without posting a repeat question as any other example I can find is much more basic than what I believe I am trying to accomplish here.

The next time you post a question, you should take a look at the help, particularly in regards to preparing a Minimally Reproduceable Example. Your code doesn't compile, you are missing types, functions, etc. Some of what I'm going to show below doesn't quite comport to what you show, but it certainly seems to meet your intention (at least to me).
I'm going to start at the bottom layer and work up. Your BotType class simply has a string and an int (with the ints incrementing). Instead of using a class, I'm going to use an enum (you should read up on these). Enums are value types. Under the covers, they end up being represented by a simple integral-valued type (like int), but with the metadata they include, they have a symbolic name as well. So:
public enum RobotType
{
Unipedal = 1,
Bipedal,
Quadrupedal,
Arachnid,
Radial,
Aeronautical,
}
Had I not included the =1, then Unipedal would have started with the default value (zero). You'll see why starting at one makes sense below. The nice thing about enums is that you can convert them to an integer, or to a string that represents their symbol. You can also parse either a string containing an integer or a string containing symbolic name to an enum instance:
var asInt = (int) RobotType.Unipedal;
var asString = RobotType.Unipedal.ToString();
bool isGoodParse = Enum.TryParse<RobotType>("1", out RobotType parsedFromInt);
isGoodParse = Enum.TryParse<RobotType>("Unipedal", out RobotType parsedFromString);
All that code works the way you might expect.
It's tempting to just do the same thing with your task types. But the names aren't valid C# symbols (they have spaces). Instead, we'll use System.ComponentModel.DescriptionAttribute to add some extra metadata to the enum values:
public enum RobotTaskName
{
[Description("Do the dishes")]
DoTheDishes = 1,
[Description("Sweep the house")]
SweepTheHouse,
[Description("Do the laundry")]
DoTheLaundry,
[Description("Take out the recycling")]
TakeOutTheRecycling,
[Description("Make a sammich")]
MakeASammich,
[Description("Mow the lawn")]
MowTheLawn,
[Description("Rake the leaves")]
RakeTheLeaves,
[Description("Give the dog a bath")]
GiveTheDogABath,
[Description("Bake some cookies")]
BakeSomeCookies,
[Description("Wash the car")]
WashTheCar,
}
But, now we can't just call ToString on the enum value to get the corresponding name. Instead, we'll use reflection to dig the name out of the Description attribute:
public static class RobotExtensions
{
public static string GetDescription<T>(this T enumValue) where T : struct, Enum
{
var enumInfo = typeof(T).GetField(enumValue.ToString());
if (enumInfo != null)
{
var attributes = enumInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
return ((DescriptionAttribute[])attributes)[0].Description;
}
}
//otherwise
return enumValue.ToString();
}
}
That code declares an Extension Method for enums (you can call it directly on an enum - any enum). It gets reflected Field Information for the enum value, checks to see if it has an DescriptionAttribute. If it does, it digs out the description and returns it. If it can't get that information, it simply returns enumValue.ToString. As a result:
RobotTaskName.DoTheDishes.GetDescription(); //returns "Do the dishes"
RobotType.Arachnid.GetDescription(); //returns "Arachnid"
The other cool thing about doing it this way, is that we can write some code that prompts the user for a particular enum value, checks it's validity, etc:
public static T? GetResponseUsingEnum<T>(string prompt) where T : struct, Enum
{
//Loop until a good answer (or no answer)
while (true)
{
Console.WriteLine($"{prompt}: Please enter one of:");
var values = (T[])Enum.GetValues(typeof(T));
foreach (var enumValue in values)
{
var description = enumValue.GetDescription<T>();
var intValue = Convert.ToInt32(enumValue);
Console.WriteLine($"{intValue}: {description}");
}
Console.Write(">> ");
var response = Console.ReadLine();
if (string.IsNullOrEmpty(response))
{
return (T?)null;
}
if (Enum.TryParse<T>(response, out var val))
{
if (values.Contains(val))
{
Console.WriteLine($"You answered: {val}");
return val;
}
}
}
}
That code shows the integer and string representations of all of the values of a particular enumerated type, and then prompts the user to enter a value. If the user enters a value out of range, then it re-prompts him/her. If the user just hits Enter, then it returns a null value. Otherwise, if the user enters a valid answer, it returns the answer (not as an integer, but as a properly typed enumerated item.
Now that the bottom layer is complete, let's work up ...
I couldn't quite tell what your Robot Task type does, or what the extra two integers where, so I called them Num1 and Num2. I also added a Perform function that "performs" the task (echoes it to the console).
public class BotTask
{
public RobotTaskName Name { get; set; }
public string Description => Name.GetDescription();
public int Num1 { get; set; }
public int Num2 { get; set; }
public BotTask(RobotTaskName name, int num1, int num2)
{
Name = name;
Num1 = num1;
Num2 = num2;
}
public void Perform()
{
Console.WriteLine($" - Peforming Task: {Name.GetDescription()} with {Num1} and {Num2}");
}
}
If you are curious, the Description property is a read-only property that calls GetDescription on the underlying RobotTaskName enumerated type.
Then I recreated your Robot type. I don't know what your intention was for the TimeElapsed property. But, I changed it to a TimeSpan from an int - because, well, that's what TimeSpans are for.
public class Robot
{
public string BotName { get; set; }
public RobotType BotType { get; set; }
public string BotTypeDescription => BotType.GetDescription();
public TimeSpan TimeElapsed { get; set; }
private List<BotTask> _tasks = new List<BotTask>();
public IEnumerable<BotTask> Tasks => _tasks;
public Robot(string botName, RobotType botType, TimeSpan timeElapsed = default)
{
this.BotName = botName;
this.BotType = botType;
TimeElapsed = timeElapsed;
}
public void AddTask (BotTask task)
{
_tasks.Add(task);
}
public void Show()
{
Console.WriteLine($"Robot: {BotName}, Type: {BotTypeDescription}, TimeElapsed: {TimeElapsed}");
foreach (var task in Tasks)
{
task.Perform();
}
}
}
Note that I also added a list of tasks that have been assigned to each robot. That includes the list, an AddTask method to add tasks to a robot, etc.
Finally, I added a Run method to the Robot class that fires the whole thing off (call it from Main). It allows you to create more than one robot and to assign more than one task to each robot. It uses the GetResponseUsingEnum method to get both the robot type and the task type. This means a consistent user interface and some healthy code reuse (if you find a bug in that function, you fix two pieces of functionality).
public static void Run()
{
var robotsList = new List<Robot>();
//loop until there are no more robots
while (true)
{
Console.Write("Enter robot name: ");)
var robotName = Console.ReadLine();
if (string.IsNullOrEmpty(robotName))
{
break; //empty robot, time to list things out
}
RobotType? robotType = null;
while (!robotType.HasValue)
{
robotType = GetResponseUsingEnum<RobotType>("Robots");
}
var robot = new Robot(robotName, robotType.Value);
robotsList.Add(robot);
Console.WriteLine("Time to add some tasks for this robot");
//get tasks - loop until no more tasks
while (true)
{
var taskName = GetResponseUsingEnum<RobotTaskName>("RobotTaskName");
if (!taskName.HasValue)
{
break; //no more tasks
}
var task = new BotTask(taskName.Value, 100, 200);
robot.AddTask(task);
}
}
//At this point, we have a fully populated list of robots, each with some tasks
foreach (var robot in robotsList)
{
robot.Show();
}
}
Finally, if you run it, the output looks like this:
Enter robot name: Robby
Robots: Please enter one of:
1: Unipedal
2: Bipedal
3: Quadrupedal
4: Arachnid
5: Radial
6: Aeronautical
>> 2
You answered: Bipedal
Time to add some tasks for this robot
RobotTaskName: Please enter one of:
1: Do the dishes
2: Sweep the house
3: Do the laundry
4: Take out the recycling
5: Make a sammich
6: Mow the lawn
7: Rake the leaves
8: Give the dog a bath
9: Bake some cookies
10: Wash the car
>> 2
You answered: SweepTheHouse
RobotTaskName: Please enter one of:
1: Do the dishes
2: Sweep the house
3: Do the laundry
4: Take out the recycling
5: Make a sammich
6: Mow the lawn
7: Rake the leaves
8: Give the dog a bath
9: Bake some cookies
10: Wash the car
>> 3
You answered: DoTheLaundry
RobotTaskName: Please enter one of:
1: Do the dishes
2: Sweep the house
3: Do the laundry
4: Take out the recycling
5: Make a sammich
6: Mow the lawn
7: Rake the leaves
8: Give the dog a bath
9: Bake some cookies
10: Wash the car
>>
Enter robot name: SecondRobot
Robots: Please enter one of:
1: Unipedal
2: Bipedal
3: Quadrupedal
4: Arachnid
5: Radial
6: Aeronautical
>> 3
You answered: Quadrupedal
Time to add some tasks for this robot
RobotTaskName: Please enter one of:
1: Do the dishes
2: Sweep the house
3: Do the laundry
4: Take out the recycling
5: Make a sammich
6: Mow the lawn
7: Rake the leaves
8: Give the dog a bath
9: Bake some cookies
10: Wash the car
>> 8
You answered: GiveTheDogABath
RobotTaskName: Please enter one of:
1: Do the dishes
2: Sweep the house
3: Do the laundry
4: Take out the recycling
5: Make a sammich
6: Mow the lawn
7: Rake the leaves
8: Give the dog a bath
9: Bake some cookies
10: Wash the car
>> 10
You answered: WashTheCar
RobotTaskName: Please enter one of:
1: Do the dishes
2: Sweep the house
3: Do the laundry
4: Take out the recycling
5: Make a sammich
6: Mow the lawn
7: Rake the leaves
8: Give the dog a bath
9: Bake some cookies
10: Wash the car
>>
Enter robot name:
Robot: Robby, Type: Bipedal, TimeElapsed: 00:00:00
- Peforming Task: Sweep the house with 100 and 200
- Peforming Task: Do the laundry with 100 and 200
Robot: SecondRobot, Type: Quadrupedal, TimeElapsed: 00:00:00
- Peforming Task: Give the dog a bath with 100 and 200
- Peforming Task: Wash the car with 100 and 200

Related

Editing users info with struct

struct person
{
public int id;
public long phone;
public string name, family, add;
public void Show()
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", id, name, family, phone, add);
}
}
class Program
{
static List<person> info = new List<person>();
static void Edit()
{
Display();
Console.Write("Choose your target ID:");
int ed = Convert.ToInt32(Console.ReadLine());
for (int i = 0; i < info.Count; i++)
{
if (ed == info[i].id)
{
Console.WriteLine("1.ID\n2.Name\n3.FamilyName\n4.PhoneNumber\n5.Address\n6.Exit to menu");
Console.WriteLine("Which part of the user info would you like to update:");
int ed1 = Convert.ToInt32(Console.ReadLine());
bool exm = false;
while (true)
{
switch (ed1)
{
case 1:
break;
case 2:
Console.Write("Enter Your Name:");
info[i].name = Console.ReadLine();
break;
case 3:
Console.Write("Enter Your FamilyName:");
info[i].family = Console.ReadLine();
break;
case 4:
Console.Write("Enter Your Name:");
info[i].phone = Convert.ToInt64(Console.ReadLine());
break;
case 5:
Console.Write("Enter Your Name:");
info[i].add =Console.ReadLine();
break;
case 6:
if (exm == true)
Main();
break;
default:
Console.WriteLine("Invalid Operation");
break;
}
}
}
}
}
I'm trying to make a program that gets users info then shows them what they can do. The program methods include input, display, search, remove, edit, all work fine but edit. I don't know how to make it work.
For edit I'm gonna get user id, then let him choose which part of that id he wants to change. In all cases I tried to replace new info but it shows me an error on info[i].would you help me to do this in this way?
You cannot change a property of a struct stored in a list; either change your struct to a class and you will then be able to modify individual properties, or change your editing routine so that it either
creates a whole new Person struct using all the data from the existing person struct with the new bit of data you want to change, and replace the old person struct in the list with the new one you've made or
gets the person out of the list into a temporary variable, changes the name, puts the temp variable back into the list
As an academic exercise I suppose it's teaching you about value types but it's a bit abstruse; perhaps your teacher is hoping you will pick up on the fact that accessing list[x] creates a copy of what is in the list at x. As there is no point editing a copy (and then throwing the copy away, as a direct edit would do) the compiler warns you that it's not possible.
You are getting the error because structs are value type.
When you do info[i] it returns value of the element at i rather than the reference to it. Modifying this value by calling setter doesn't change anything in the actual struct instance. Hence the error.
A naive workaround would be
info[i]=new person{name= Console.ReadLine()};
If not for an assignment, you should definetely use classes in these cases

How can I create random objects from a bunch of classes (herited classes)

I'm sorry if there is a similar question, tried searching but didn't find an adequate response for my use.
I have 5 classes that herits from one class (spaceshipclass) and I need to create random objects from each class and store them in a binary tree.
with each one of the objects, two random integers as shown in the code bellow.
public class spaceships
{
int cost;
int combatPower;
private Random rand = new Random();
public spaceships(int cost, int combatPower)
{
this.cost = cost;
this.combatPower = combatPower;
cost = rand.Next(10000, 1000000);
combatPower = rand.Next(20, 100);
}
}
public class Patrol : spaceships
{
public Patrol (int cost,int combatPower) : base(cost,combatPower)
{
}
}
the second class is one of the inherited classes.
I hope someone can help me.
There seems to be a disconnect between the desired functionality and the posted code, as your spaceships class takes in a cost and combatPower in its constructor, but then ignores that and calculates those values itself. Because of this, I'm going to ignore that particular implementation and just go ahead and calculate those values before constructing the random objects, as your question title requests. Keep in mind that my solution allows you to remove the private Random rand field of your spaceships class entirely.
You could use a simple switch statement to determine which type of spaceships to create, and then add them to your collection (you mention a binary search tree but that's an implementation detail that doesn't really matter here, so long as it is of type spaceships to support the polymorphism your question mentions).
Random rand = new Random();
for (int i = 0; i < numSpaceshipsRequired; i++)
{
int typeOfSpaceship = rand.Next(0, 5);
int cost = rand.Next(10000, 1000000);
int combatPower = rand.Next(20, 100);
switch (typeOfSpaceship)
{
case 0:
collection.Add(new Patrol(cost, combatPower));
break;
case 1:
collection.Add(new Cruiser(cost, combatPower));
break;
case 2:
collection.Add(new Frigate(cost, combatPower));
break;
case 3:
collection.Add(new Fighter(cost, combatPower));
break;
case 4:
collection.Add(new Stealth(cost, combatPower));
break;
}
}

How Can I Get The Value of an Item in an Array via Reflection

Skip to the third paragraph for the question.
Context: I'm creating a 2D spaceship game, and one of the game mechanics is routing power to the 7 different parts of the ship to suit the current situation you're in. There are presets that you can switch to at any time, called power configurations. I have the power configurations stored in 3 different arrays, like so:
int[] powerConfiguration1 = new int[7] {10,10,10,10,20,20,20};
int[] powerConfiguration2 = new int[7] {20,20,20,10,10,10,10};
int[] powerConfiguration3 = new int[7] {10,20,10,20,10,20,10};
When you switch configurations, it calls a method for doing so. The method makes some calculations to determine how long it will take to switch configurations. However, instead of making a switch statement and copy/pasting the code several times in the case of the player switching to any of the three configurations, I want to use PropertyInfo in System.Reflections to choose which property I need to pull values from.
Question: The problem is that I don't know how to get an item from an array. Here is what I have so far, where I'm attempting to determine how much power will need to be rerouted in total and adding it all to a variable. 0 is the index in the configuration at which I have decided to store the shield power. powerToShields is the current power being routed to the shields.
void switchConfiguration(int number) {
PropertyInfo powerConfiguration = GetType().GetProperty("powerConfiguration" + number);
int powerToReroute = 0;
powerToReroute += Mathf.Abs(powerToShields - powerConfiguration[0]);
Could someone please explain what I'm doing wrong and/or show me how to fix it? Or, is there a better way to do this?
EDIT 1: This is coded in C# (Unity).
Side thought
I guess my first question is why not store the arrays in a list. So, instead of powerConfiguration1, powerConfiguration2, powerConfiguration3, why not just store a list of int[], so
List<int[]> powerConfigurationList = new List<int[]>;
powerConfigurationList.Add(new int[7] {10,10,10,10,20,20,20});
powerConfigurationList.Add(new int[7] {20,20,20,10,10,10,10});
powerConfigurationList.Add(new int[7] {10,20,10,20,10,20,10});
That way you can get the item via:
powerToReroute = (powerConfigurationList[number])[0]
Answer to your question
However, assuming that there is some good reason that you can't, and in order to answer your exact question, do the following:
...
PropertyInfo powerConfiguration = GetType().GetProperty("powerConfiguration" + number); //this line is taken from your example above
//then you need to do something like the below
var value = (int[])powerConfiguration.GetValue(instanceThatHasTheProperty);
int powerToReroute = 0;
powerToReroute += Mathf.Abs(powerToShields - value[0]);
From your code snippet, I see you have GetType().GetProperty("powerConfiguration" + number);. I'm not sure what the actual instance is that your getting that type from. So you need to replace instanceThatHasTheProperty in my above snippet, by whatever instance you're trying to get the property's value from.
The thing that is immediately obvious to me is that the code is unnecessarily obfuscated and seems an awful lot like an X-Y problem. Using jagged arrays and reflection seems like a whole lot of work to end-around object oriented programming. My recommendation would be to create a class to store your power configurations, store multiple power configurations in a list, and then select the configuration from the list.
Sample Class for Power Configurations
public class PowerConfiguration
{
public int ID { get; set; }
public string Name { get; set; }
public int Shields { get; set; }
public int Weapons { get; set; }
public int LifeSupport { get; set; }
public int Propulsion { get; set; }
}
Inserting and Accessing your Power Configurations
public class DoStuff
{
public void LoadPowerConfiguration()
{
// Create a List to store configurations
List<PowerConfiguration> allPowerConfigurations = new List<PowerConfiguration>();
// Add some mock data to the list
allPowerConfigurations.Add(new PowerConfiguration()
{
ID = 0,
Name = "Balanced Combat",
Shields = 30,
Weapons = 30,
LifeSupport = 20,
Propulsion = 20
});
allPowerConfigurations.Add(new PowerConfiguration()
{
ID = 1,
Name = "Offensive",
Shields = 20,
Weapons = 50,
LifeSupport = 10,
Propulsion = 20
});
// Figure out which ID you what (eg. from the user pressing '0')
int selectedConfigurationID = 0;
// Get the configuration from the list
PowerConfiguration selectedConfiguration =
allPowerConfigurations.FirstOrDefault(p => p.ID == selectedConfigurationID);
// Now perform your operations against the PowerConfiguration object's properties
int powerToShields = 100;
int powerToReroute = 0;
powerToReroute += Math.Abs(powerToShields - selectedConfiguration.Shields);
}
}

C# constant list of values

I want control a other device with a C# program, this device have something like registers for read and write. So I searching something to enter all register numbers to get a better human readable code and to have central config place. All the registers using a uint value.
I searching something like this:
public enum EISCJoin : uint
{
Read_Connect = 1,
Read_Temp = 2,
Read_Switch = 3,
Write_Connect = 1,
Write_Temp = 2,
Write_Switch = 3,
}
switch (args.Sig.Number) //uint value
{
case (uint)EISC.Read_Connect:
{
args.SendValue[(uint)Write_Connect] = 1;
...
break;
}
case (uint)EISC.Read_Temp:
{
args.SendValue[(uint)Write_Temp] = 1;
...
break;
}
case (uint)EISC.Read_Switch:
{
args.SendValue[(uint)Write_Switch] = 1;
...
break;
}
}
My problem is that I don't want cast the ENUM value thousands of times in my source code and what I know is that a implicit conversation is not possible with enum.
Have someone a good idea to create a constant list of uint values?
you need to cast the number instead:
switch (args.Sig.Number)
to
switch ((EISCJoin)args.Sig.Number)
The other way is to use a static class and constant uints:
static public class EISCJoin
{
public const uint Read_Connect = 1;
public const uint Read_Temp = 2;
// and so on
}
I must work with a framework of the manufacturer and have no access to all the classes, it is not a option to modify all classes to the enum.
I using a value the most time only 1-2 times, so the most time I cast the value for 1 time use.
It looks like I must use the static class with the const uint variables.
Thanks for your help

how to make a certain number of variables with a different name?

I've started programming in C# to develop some console applications and I was wondering how I could make a certain number of variables with a different name in a more efficient way. For now I'm doing something like this:
for(int i=1; i<=x; i++)
switch(i) {
case 1:
Player player1=new Player(i, x);
break;
case 2:
Player player2=new Player(i, x);
break;
case 3:
Player player3=new Player(i, x);
break;
case 4:
Player player4=new Player(i, x);
break;
case 5:
Player player5=new Player(i, x);
break;
case 6:
Player player6=new Player(i, x);
break;
}
I'm just wondering whether there are more effecient ways to solve this and what those ways are.
You'd be better off making an array:
var players = new Player[x];
for (int i = 0; i < x; i++)
{
players[i] = new Player(i, x);
}
or use Linq:
var players = Enumerable.Range(0, x)
.Select(i => new Player(i, x))
.ToArray();
You can then reference the players you created with.
var player1 = players[0]; // Note: array indexes start at 0
Of course, you may not actually need to use arrays, specifically. Many other collection classes might suit your problem better.
Further reading:
Arrays (C# Programming Guide)
Collections (C# and Visual Basic)
You could make a List of players
var players = new List<Player>;
for (int i = 0; i < x; i++)
{
players.add(new Player(i, x));
}
Then the memory would be distributed at runtime.
I prefer not to use array's because you have to know in advance what size they will be. With lists you can dynamically assign value's and It will only ever take up as much space in memory as the list is in its current state.
I don't program in C# but it seems you're creating local variables : they are valid only in your loop.
Name your variables outside of the loop, then create them inside of it. You will have to test if they exist to work with them.
Just for a trick:
partial class Player {
public Player(int i, int x) {
this.Ordinal=i;
}
public int Ordinal {
get;
set;
}
public static int Total {
get;
set;
}
public delegate Trick Trick(out Player x);
public static Trick Create(out Player x) {
x=new Player(++Player.Total, 0); // the second int doesn't matter
return Create;
}
}
partial class TestClass {
public static void TestMethod() {
Player mom, dad, brother, sister, me;
Player.Create(out mom)(out dad)(out brother)(out sister)(out me);
}
}
You might want to define another way to implement the Total once you have more than one series of Player.

Categories