how to Implement the IReadOnlyList interface to let other classes read from your internal list.

122 Replies
333fred
333fred4y ago
Well, I would start by letting VS auto-do most of it for you. Press ctrl+. on IReadOnlyList and select one of the quickfixes offered for implementing the interface
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Well, if you're learning, see what they do 🙂 There are two for implementing the interface
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Which one did you do?
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Well, what about what it generated confuses you? I can explain stuff, but only if you tell me what you don't get
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Interfaces have nothing to do with constructors
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
What is it here?
sibber
sibber4y ago
an enumerator is something you can iterate or more accurately enumerate so foreach for example works on enumerators so does linq
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
I don't know? I'm asking you? You said I'm not totally sure what it does I don't know what it you meant
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Again, that's a lot of code. Which things confuse you
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Well, in a real application I'd tell you just use the List<Pokemon> and delete the rest of the code
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
But the idea is that you're trying to make PokemonParty represent a list (not the C# type, the English concept)
Renn
Renn4y ago
Is there a particular reason you want to implement IReadOnlyList?
333fred
333fred4y ago
By real application I meant one for production. Not one for learning
Renn
Renn4y ago
just to learn it? Because if it's an exercise, go for it. But practically speaking you wouldn't do that in this case.
333fred
333fred4y ago
Yeah, that's what I meant Are you generally familiar with what an interface is at all?
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
An interface is a contract It says "I promise that the type that implements me has these methods and properties, and you can call them"
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
It allows you to do what's called encapsulation, which is making sure that implementations aren't tied together For example, let's say you have a list of pokemon Maybe that list is implemented by List<Pokemon> Maybe it's actually stored in a database, and calling list[1] needs to go look in the database to find it You don't know, and you don't care: all you know is that you have something that logically represents a list and can be indexed
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
And, importantly, you can easily switch it out without the thing that uses the list caring
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
You wouldn't. There are built-in objects that already implement IList<T>. Like List<T>. You can of course make your own class that implements IList<T> and then pass it into anything that takes the interface, but there would be no reason to. In your case
333fred
333fred4y ago
Well, you're trying to implement IReadOnlyList<Pokemon>. So you need to comply with the contract that it says you must have And that means implementing the methods and properties defined in the interface
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
You can let the IDE scaffold it for you
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Well, all the stuff the IDE generated? It put the methods and properties in for your Now you need to give them actual bodies Rather than just throwing NotImplementedExceptions
Renn
Renn4y ago
If you derive from the interface, the IDE will show you some squiggles under the interface name. One of the options is "Implement Interface", which will create all the framework for the stuff the interface needs. Then, as @Orannis says, you have to actually write the code.
333fred
333fred4y ago
That was the start of this conversation 🙂
Renn
Renn4y ago
Yeah but I got the sense they haven't even gotten that far Of course I could be wrong! oh nm I see it up there. Must have missed it XD
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Well, you need to store them in something
Renn
Renn4y ago

public class PokemonParty : IReadOnlyList<Pokemon>
{
private List<Pokemon> internalList = new List<Pokemon>();

public PokemonParty()
{
}

Pokemon IReadOnlyList<Pokemon>.this[int index] => internalList[index];

public int Count => internalList.Count;

public IEnumerator GetEnumerator()
{
return internalList.GetEnumerator();
}

IEnumerator<Pokemon> IEnumerable<Pokemon>.GetEnumerator()
{
return internalList.GetEnumerator();
}
}

public class PokemonParty : IReadOnlyList<Pokemon>
{
private List<Pokemon> internalList = new List<Pokemon>();

public PokemonParty()
{
}

Pokemon IReadOnlyList<Pokemon>.this[int index] => internalList[index];

public int Count => internalList.Count;

public IEnumerator GetEnumerator()
{
return internalList.GetEnumerator();
}

IEnumerator<Pokemon> IEnumerable<Pokemon>.GetEnumerator()
{
return internalList.GetEnumerator();
}
}
I think that will do it (I haven't tested) doing that will implement the interface. But of course you still need to add functions to add and remove Pokemon from your internalList
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
You should move internalList to your class I revised the code
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
Did you see where I moved it above? It's right after the class declaration.
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
No. Do you know what static means?
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
it wants a reference? what do you mean by that?
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
you shouldn't be putting the list in another class why do you want to do that?
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
okay cool
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
those aren't the adding and removing functions. GetEnumerator returns a (you guessed it) enumerator that allows you to iterate through the items in the list. It's the thing that allows you to use foreach on something, for example. For adding/removing, you just need to create the appropriate functions. Something like this is a baseline:
public void Add(Pokemon pokemon) {
internalList.Add(pokemon);
}

public void Remove(Pokemon pokemon) {
internalList.Remove(pokemon);
}
public void Add(Pokemon pokemon) {
internalList.Add(pokemon);
}

public void Remove(Pokemon pokemon) {
internalList.Remove(pokemon);
}
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
I think that probably covers the basics, yes.
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
Well, no, you don't strictly need the interface. This is why we were saying earlier that for this use case, the interface is not helpful. But I suppose as an exercise to learning about interfaces and how to use them, it's instructive. Consider a function like this:
public bool IsPokemonInParty(IReadOnlyList<Pokemon> party, Pokemon pokemon)
{
foreach(var partyMember in party)
{
if (partyMember == pokemon)
return true;
}

return false;
}
public bool IsPokemonInParty(IReadOnlyList<Pokemon> party, Pokemon pokemon)
{
foreach(var partyMember in party)
{
if (partyMember == pokemon)
return true;
}

return false;
}
You can call this function like so:
var party = new PokemonParty();
var pikachu = new Pokemon( /* Omitted: parameters for creating a new Pokemon */ );

party.Add(pikachu);
// Omitted: Add more Pokemon

var isInParty = IsPokemonInParty(party, pikachu);
Console.WriteLine(isInParty); // TRUE
var party = new PokemonParty();
var pikachu = new Pokemon( /* Omitted: parameters for creating a new Pokemon */ );

party.Add(pikachu);
// Omitted: Add more Pokemon

var isInParty = IsPokemonInParty(party, pikachu);
Console.WriteLine(isInParty); // TRUE
As you can see, your function IsPokemonInParty is agnostic. All it cares about is the interface. We passed it a PokemonParty and it works, because PokemonParty implements IReadOnlyList<Pokemon>. You can pass it literally any other object that implements IReadOnlyList<Pokemon>.
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
what values?
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
any Pokemon you put into the list will retain its values, yes.
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
If you want, yes
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Renn
Renn4y ago
Make sure your classes are in different files. Your Program.cs shouldn't contain any classes.
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
could you show how you print it? just to give you the correct answer
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
yeah. what is done here is that, console.writeline if gets an object(and many parts in c# that output strings) uses .ToString() onto that. and as default you get the fully qualified Name so you have 2 solutions: - override ToString() in your pokemon class - print and format the properties yourself where you are outputting it. Console.WriteLine($"{Pokemon.Name} {Pokemon.Power} ... "); it depends on what you want. if its just debug info, override tostring and format it pretty
Poller
Poller4y ago
thats how a override could look like
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
i dont know how your pokemon class looks like. is it posted above? mine was just a example how to code it. property names may differ
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
yeah. i dont know if your pokemon class has a propperty called "Name".
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
this is just how you instanciate it. can you show the class itself? i have a suspicion what is going on
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
hmm Name should be accessible. can you show me your new Console.WriteLine line?
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
now the output. i want to see code 😉
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
i dont seh the mentioned .Name here. could you show how you did try to write it?
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
show me how you would write it
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
myobject is never in your foreace declared.. in THIS code. change line 2 into how you would write the .Name property g2g. i look here later (promised)
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Poller
Poller4y ago
so. how does this line look like if you try to use the name property. i cant help you propperly if i dont know what youre doing wrong
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Implement ToString on Pokemon, and then just writeline the pokemon
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
The class
333fred
333fred4y ago
How to override the ToString method - C# Programming Guide
Learn how to override the ToString method in C#. Every class or struct inherits Object and gets ToString, which returns a string representation of that object.
Poller
Poller4y ago
i still dont know what you tried. if you post this maybe tag me. for now i dont have enough to help you.
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
You do it in every class you want to have a good ToString in
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
You implement it on your custom party type, and your pokemon type Your party goes through its internal list and calls it on every pokemon
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Give it a try first
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Because you didn't implement ToString on Pokemon
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
No
MODiX
MODiX4y ago
Orannis#3333
Your party goes through its internal list and calls it on every pokemon
React with ❌ to remove this embed.
333fred
333fred4y ago
But start with just pokemon Get that printing nicely Then do the whole party
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Yep
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Do this
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Sure you do
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
Show your code
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
333fred
333fred4y ago
None of this is your ToString override
Unknown User
Unknown UserOP4y ago
Message Not Public
Sign In & Join Server To View
Accord
Accord4y ago
✅ This post has been marked as answered!

Did you find this page helpful?