I will explain my issue with this example:
ICollection<Employee> listOfEmployee = new List<Employee>();
//listOfEmployee = Some code;
In C#, List<T> inherits from IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T> interfaces. So this means List<T> have all methods that these intercafes have.
In this example above why do we sometimes use
ICollection<Employee> listOfEmployee = new List<Employee>();
or
IEnumerable<Employee> listOfEmployee = new List<Employee>();
etc... instead of
List<Employee> listOfEmployee = new List<Employee>();
this? Is there any performance benefits or something?
In general, it's good practice to use the simplest type you need. It's more flexible in the long run if you decide to change the higher level type later on. For example, this works with no changes to your code:
If you were to use the highest level class like your second example instead:
This would throw a compile-time error, even though you're only using methods from the ICollection<> interface. Since you don't need to access all of the higher-level functionality you get in a List<>, it's more maintainable this way to use ICollection<>.
Edit: It's also a good way to indicate what type of operations you plan on using with your object. If you only intend to iterate through the list, then maybe IEnumerable is the way to go. But if you want to add and insert objects later on, then you might use a List there instead