2

I'm an inexperienced C# hobbyists who tries to learn a bit of c# when I have a little bit of time left, like now lately.

I'm trying to figure out when to use ICollection<T>.

I have searched on YouTube and online documentation. But they cover "how to use it", not why and when to use it. For example a title like below would be far more helpful to me:

"Hey, are you always using List<T>? Find out how ICollection<T> could be more helpful!"

Nothing seems to be out there. I assume one has to learn this in some indirect way. Either way, can anyone provide and answer and even perhaps an example why one would use this, instead of one of lists, arrays and whatnot?

Edit: I don't even know how to ask a question because I don't know what I'm talking about. Here's the code which triggered my interest:

ICollection<ValidationResult> validationResultList = new List<ValidationResult>();

What is happening here?

Valmont
  • 328
  • 1
  • 2
  • 11
  • No CodeCaster, but thank you for responding. I know what an interface is for. My question is to why use said collection, not what an interface is for. – Valmont Apr 20 '23 at 20:50
  • The same principle that applies to all interfaces, also applies to this particular interface... You use it when you want to use a collection parameter whose implementation type you don't care about (but on which you're going to access members present on that interface), or when you want to return one. – CodeCaster Apr 20 '23 at 20:51
  • 2
    When you use `List`, you are using `ICollection` – LarsTech Apr 20 '23 at 20:52
  • Let me try differently: One could use a list, an array, and arraylist. Very flexible. Yet one chooses rather to implement their own collection (I suppose) with ICollection. Why? What problem does that solve? – Valmont Apr 20 '23 at 20:53
  • 1
    No, you don't have to implement your own collection when using it. You just say "this method returns an ICollection, and which implementation of that interface it will return, you should not care about". That's what an interface does. It doesn't mean you have to implement it in your own type. Stating that your method accepts or returns an ICollection _is_ what's flexible. It allows you to refactor your code to one day return an array instead of a list, and callers won't have to change a thing, and it allows your callers to pass any collection as long as it implements that interface. – CodeCaster Apr 20 '23 at 20:54
  • 2
    It's most useful as an _input_ parameter. I don't need to know whether I am being given a `List` or a `T[]` in order to reverse the contents. Why would I force callers to always convert their list to an array in order to call my 'Reverse' method? – Andrew Williamson Apr 20 '23 at 20:56
  • @CodeCaster Yes I can show the code. It's in (timestamp included): https://youtu.be/Bu-4WXFcMkc?t=695 – Valmont Apr 20 '23 at 21:08
  • Sorry, I have rewound a minute and watched two and am screaming at his typos, the indentation, his mouse clicks to position the caret, the overall design of a custom validator (including the class name, "Check", really?), the (lack of) speed and explanation and the floating solution explorer. I am physically and mentally unable to watch tutorial videos. – CodeCaster Apr 20 '23 at 21:12
  • 1
    That being said: declaring a local variable as an interface is usually not necessary. In this case it isn't, because it's passed to a method that accepts an ICollection, so an instance of any class that implements that interface would suffice. – CodeCaster Apr 20 '23 at 21:18
  • 1
    CodeCaster + AndrewWilliamson thanks. The combined information as well with the answer by @chart solves it for me. Thanks everybody! Now I understand. – Valmont Apr 20 '23 at 21:21
  • 1
    Exactly this was the final bit which answered all of my questions for now: **That being said: declaring a local variable as an interface is usually not necessary. In this case it isn't, because it's passed to a method that accepts an ICollection, so an instance of any class that implements that interface would suffice** – Valmont Apr 20 '23 at 21:23

1 Answers1

3

The simple answer is, use ICollection<T> when you need something more abstract than List<T> (or other collection, such as HashSet<T>).

You use the interface because you may not care about receiving List specifically. You care about receiving an object that implements the methods contracted by the interface. You just want to know that when something is passed into your method, and you then call myArgument.neededMethod(), that you know for certain that this method will have been implemented.

jocha
  • 58
  • 4
  • see the little code snippet in my original (edited) post. What is achieved with that code? Thanks. – Valmont Apr 20 '23 at 21:16
  • 1
    In your example, you are instantiating a new `List`. The reason you can use `ICollection` as the type is due to polymorphism. If that isn't something you're familiar with, look it up and spend some time trying to understand the concept and it really underpins Object-Oriented Programming (OOP), C# and Java in particular. – jocha Apr 20 '23 at 21:33
  • 1
    In practice, for your example, there is effectively no difference between: `ICollection validationResultList = new List();` and `List validationResultList = new List();` – jocha Apr 20 '23 at 21:35
  • Yes, thank you. I have learned this through comments. This was just the wrong code to be introduced to this generic collection interface. Would it have been in a parameter its use would have been more easily clear to me. Thanks bro. – Valmont Apr 20 '23 at 21:42