C
C#3mo ago
Shrow

Need help selecting objects in a list

This code is simply a testing file so I can figure out how to make this work. In this file I created the class Hero with three int values id, lvl, hp. A friend explained how to set this up so that I can create objects via this class. I'm not sure why the int's need to be declared three times or what the 'this' statement does or why it is needed, an explanation on this would be nice but not necessary at the moment. What I'd like to do in this file is allow the user to pick a Hero. line 29 creates the Hero list, line 30 and 31 allow user input. 33 and 34 are objects, the test Hero's named dee and goo. Lines 37 and 47 are my various attempts at getting trying to get the listing to appear and for me and to be able to select something in the list but unfortunately the foreach and for don't work, I tried LinqQuery but I'm not even sure how that works. On lines 57 to 61 you can see testing on object manipulation but unfortunately it's hard coded to the first Hero 'dee'. I don't know what I would type in instead to allow for a more generic object value changes depending on which Hero was selected. Please I am a beginner at C# coding and I do not understand all the terms so please if possible answer in layman's terms so I can understand better. Thank you.
No description
No description
53 Replies
Angius
Angius3mo ago
an explanation on this would be nice but not necessary at the moment
Go through the $helloworld tutorials, they will explain things like variables, classes, objects, instances, and so on.
What I'd like to do in this file is allow the user to pick a Hero. line 29 creates the Hero list
No heroes are ever added to the list, the list is and will be empty
Angius
Angius3mo ago
You have variable dee with a hero, variable doo with a hero, but none of them are in the list Trying to foreach through an empty list just does nothing
Shrow
ShrowOP3mo ago
Oh now how do I add objects to the the list then? The same friend told me that a the code on the learn Microsoft is poorly written and was going to teach me bad habits. Something about “if this code was presented to a professor, they would fail it.” At my level I cant tell what’s wrong with it. Il go back to it. It’s better then making no progress. Thank you for help
Angius
Angius3mo ago
In my experience, it's often the professors who know fuck all about programming Initializing a new list with elements is simple, there are a few ways: The long way:
var list = new List<int>();
list.Add(1);
list.Add(71);
list.Add(881);
var list = new List<int>();
list.Add(1);
list.Add(71);
list.Add(881);
List initializer:
var list = new List<int>(){ 1, 71, 881 };
var list = new List<int>(){ 1, 71, 881 };
Collection expression:
List<int> list = [1, 71, 881];
List<int> list = [1, 71, 881];
In your case, it will be a list of Heros, so for example
List<Hero> heroes = [
new Hero("Bob", 1, 2, 3),
new Hero("Matilda", 6, 7, 8),
// etc...
];
List<Hero> heroes = [
new Hero("Bob", 1, 2, 3),
new Hero("Matilda", 6, 7, 8),
// etc...
];
Shrow
ShrowOP3mo ago
Noted il try this! Thank you
TizzyT
TizzyT3mo ago
1) this keywork is to refer to the current instance of what ever object the class made. So if you have a Hero class and later you make a Hero object. The this keyword is a way for that object to reference itself. 2) maybe a record (instead of class maybe simpler in your case). 3) To list all the Heros loop through and print the Hero.
public record Hero(string Name, int Id, int Lvl, int Hp);

List<Hero> heros = new();
heros.Add(new("dee", 1, 3, 30));
heros.Add(new("goo", 1, 4, 40));

// List Heros
for(int i = 0; i < heros.Count; i++);
Console.WriteLine($"{i} : {Heros[i]}");

// Get user input
Hero? userSelection = null;
while (userSelection is null)
{
Console.WriteLine("Select a Hero");
string userInput = Console.ReadLine();
if (int.TryParse(userInput, out int index) && index > -1 && index < heros.Count)
{
userSelection = heros[index];
}
else
{
Console.WriteLine("Invalid input, Try Again");
}
}

// Print the selected hero
Console.WriteLine($"You Selected the Hero: {userSelection.Name}");
public record Hero(string Name, int Id, int Lvl, int Hp);

List<Hero> heros = new();
heros.Add(new("dee", 1, 3, 30));
heros.Add(new("goo", 1, 4, 40));

// List Heros
for(int i = 0; i < heros.Count; i++);
Console.WriteLine($"{i} : {Heros[i]}");

// Get user input
Hero? userSelection = null;
while (userSelection is null)
{
Console.WriteLine("Select a Hero");
string userInput = Console.ReadLine();
if (int.TryParse(userInput, out int index) && index > -1 && index < heros.Count)
{
userSelection = heros[index];
}
else
{
Console.WriteLine("Invalid input, Try Again");
}
}

// Print the selected hero
Console.WriteLine($"You Selected the Hero: {userSelection.Name}");
Hope i didnt make any mistake
Shrow
ShrowOP3mo ago
I'm getting the error "CS8936 Feature 'collection expressions' is not available in C# 10.0. Please use language version 12.0 or greater." I didn't realize my file was not updated to the most recent version, real quick could you tell me how to do that?
Angius
Angius3mo ago
Ah, seems your project uses an old version of .NET, .NET Framework probably $newproject
MODiX
MODiX3mo ago
When creating a new project, prefer using .NET over .NET Framework, unless you have a very specific reason to be using .NET Framework. .NET Framework is now legacy code and only get security fix updates, it no longer gets new features and is not recommended. https://cdn.discordapp.com/attachments/569261465463160900/899381236617855016/unknown.png
Angius
Angius3mo ago
For reference
TizzyT
TizzyT3mo ago
double click on the project file and add
<LanguageVersion>latest</LanguageVersion>
<LanguageVersion>latest</LanguageVersion>
Shrow
ShrowOP3mo ago
Oh I will test this out for sure thank you
Angius
Angius3mo ago
The easiest way would be to make a new project without the (.NET Framework) suffix and just copy your code over, IMO Changing the language version will hardly be enough You would need to change the framework version as well, best to keep them in sync .NET 8 -> C# 12 Ah, wait, C# 10 is .NET 6, right? In that case, yeah, updating the language version and framework version will be enough
TizzyT
TizzyT3mo ago
i dont remember either lol
Angius
Angius3mo ago
Right-click the project, open properties, you'll be able to change it there
TizzyT
TizzyT3mo ago
I just know that 10 is far back enough that if you have .net installed you most likely are upto date enough
Shrow
ShrowOP3mo ago
Hmm I only have .Net 8.0 as the newest option. I guess my visual studio is out of date
Angius
Angius3mo ago
That's the newest one
TizzyT
TizzyT3mo ago
.Net8 is definitely upto date lol um id say just change the language version and you should be good, follow what @ZZZZZZZZZZZZZZZZZZZZZZZZZ said Tho I have never changed it from there so idk
Shrow
ShrowOP3mo ago
well it was out of date just from 17.10.4 to 17.11.4 after update i'l fix my file
TizzyT
TizzyT3mo ago
thats the visual studio version, but I guess you can update that too if you want.
TizzyT
TizzyT3mo ago
I tend to just double click on the project file (the green one):
No description
Shrow
ShrowOP3mo ago
Okay good to know what the project file was because I wasn't 100% sure
TizzyT
TizzyT3mo ago
then just add the <LanguageVersion> like so:
No description
Angius
Angius3mo ago
Change that netstandard2.0 to net8.0
TizzyT
TizzyT3mo ago
source generators
Angius
Angius3mo ago
Ah, carry on then
TizzyT
TizzyT3mo ago
🙂
Shrow
ShrowOP3mo ago
okay it's working now to actually print the list @TizzyT What's a record keyword? Is that similar to class?
Angius
Angius3mo ago
It's a spicy class, yes Compiles to a class, but has a bunch of added functionality And is immutable by default
TizzyT
TizzyT3mo ago
oh yeah, i probably shouldve mentioned that
Shrow
ShrowOP3mo ago
@TizzyT I am using it right? I'm seeing lots of red
No description
TizzyT
TizzyT3mo ago
move the public record outside of the method (before Main) indent the line:
Console.WriteLine($"{i} : {Heros[i]}");
Console.WriteLine($"{i} : {Heros[i]}");
same line, change the H to h You can change
string userInput = Console.ReadLine();
string userInput = Console.ReadLine();
to
string? userInput = Console.ReadLine();
string? userInput = Console.ReadLine();
or
string userInput = Console.ReadLine()!;
string userInput = Console.ReadLine()!;
if you really want to get rid of the squigglies once this works you can then move onto make Hero a class 😛
Shrow
ShrowOP3mo ago
IT's working! Thank you, Tizzy What do you mean? It's already a class with the 'this' statements right?
TizzyT
TizzyT3mo ago
the this statement only allows an object to reference itself. It doesnt make something a class right now you have a Heros as records. You can modify this to have things like lvl, hp, etc be changed but as it is now you cannot change it without creating a whole new instance with the "with" keyword so like I mentioned you can modify what you have now to
public record Hero
{
// implementation
}
public record Hero
{
// implementation
}
or you can just go back to a class either of which will look pretty similar
Shrow
ShrowOP3mo ago
So I can't do Doo.hp + 5; without creating a whole new instance?
Angius
Angius3mo ago
I'd stick with a class Let's keep it simple With records, not exactly, no With classes, yes
Shrow
ShrowOP3mo ago
Why make it a record then?
Angius
Angius3mo ago
Takes less code That's mostly the reason And such immutability is sometimes desired Not in this case, though
Shrow
ShrowOP3mo ago
oh okay
TizzyT
TizzyT3mo ago
public class Hero
{
public string Name { get; set; }
public int Id { get; set; }
public int Lvl { get; set; }
public int Hp { get; set; }

public Hero(string name, int id, int lvl, int hp)
{
Name = name;
Id = id;
Lvl = lvl;
Hp = hp;
}
}
public class Hero
{
public string Name { get; set; }
public int Id { get; set; }
public int Lvl { get; set; }
public int Hp { get; set; }

public Hero(string name, int id, int lvl, int hp)
{
Name = name;
Id = id;
Lvl = lvl;
Hp = hp;
}
}
Shrow
ShrowOP3mo ago
So this is the ideal way to do it? I will test
Angius
Angius3mo ago
A class? Yes
TizzyT
TizzyT3mo ago
I mean you can experiment and learn the advantages and disadvantages first hand 🙂
Shrow
ShrowOP3mo ago
And it works, Thank you!
TizzyT
TizzyT3mo ago
It doesnt have to take more code, you can turn it into a single line too
public class Hero(string Name, int Id, int Lvl, int Hp);
public class Hero(string Name, int Id, int Lvl, int Hp);
The reason to use records is because it has some things implemented behind the scenes which are nice in certain scenarios like ToString is already implemented for you etc like mentioned earlier it is basically just a fancy class and I guess a
record struct
record struct
is a fancy struct
Angius
Angius3mo ago
This won't work
Shrow
ShrowOP3mo ago
oh thanks for tip however I'd prefer to keep it longer for now.
Angius
Angius3mo ago
Primary constructor parameters in classes are just parameters. Only records compile them into properties.
Shrow
ShrowOP3mo ago
good to know, I don't like declaring values in the constructor anyway.
TizzyT
TizzyT3mo ago
oops, apologies: this then:
class Hero(string name, int id, int lvl, int hp)
{
public string Name { get; set; } = name;
public int Id { get; set; } = id;
public int Lvl { get; set; } = lvl;
public int Hp { get; set; } = hp;
}
class Hero(string name, int id, int lvl, int hp)
{
public string Name { get; set; } = name;
public int Id { get; set; } = id;
public int Lvl { get; set; } = lvl;
public int Hp { get; set; } = hp;
}
Angius
Angius3mo ago
This would work, yes
Want results from more Discord servers?
Add your server