Interested, does approaches has any differences.
So, I created two snippets.
Snippet A
List a = new List();
a.Add(4);
a.Add(6);
int
In general, concrete class/interface methods should be favored over generic implementations because, well, the later are generic and the data structure is supposed to take its specifics into account. For instance, linked list should not provide indexer because it cannot be implemented efficiently. Ideally, every data structure will define a its own method with the same signature as the corresponding generic extension method when it can provide better implementation, and compiler will handle that properly. This can be treated as specialization and unfortunately is not supported very well as in C++ templates. The implementation of Enumerable.First
is a good example of a "workaround" rather than a solution - it does optimization for a specific BCL interface, but cannot handle a custom data structure (like linked list) which can provide the same information much better than using the generic implementation. And it's even worse for the Enumerable.Last
.
To resume, if you program against specific classes/interfaces, use their methods when possible. If you are programming against standard generic interfaces, well, you have no other options anyway (except defining your extension methods that shadow the standard ones, but that usually leads to clashes).