9

Why IEnumerable<T>.Reverse() returns the reversed collection with the original collection and List<T> reverses the original collection itself? This is somewhat confusing to me since List<T> inherits from IEnumerable<T>.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
Prasanna
  • 187
  • 1
  • 10

6 Answers6

10

Because they're two different methods.

List<T>.Reverse is an instance method on List<T>. This modifies the List in place.

Enumerable.Reverse<T> is an extension method on IEnumerable<T>. This creates a new sequence that enumerates the source sequence in reverse order.

You can use the latter on a List<T> by calling as a static method:

var list = new List<string>{"1","2"};
var reversed = Enumerable.Reverse(list)

Or by casting to IEnumerable<T>:

IEnumerable<string> list = new List<string>{"1","2"};
var reversed = list.Reverse();

In both these cases, list remains unchanged and reversed when enumerated returns {"2","1"}.

Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • I've added an Extension method 'Reverse**d**' that just wraps Ienumerable.Reverse - quite often you want immutability, and now you can just call it without any casting or other boilerplate code. – Dirk Boer Jul 06 '17 at 05:42
9

Conceptually, this may be because IEnumerable is used when you want to represent an immutable collection of items. That is, you only want to read the items in the list, but not add/insert/delete or otherwise change the collection. In this view of the data, returning a new IEnumerable in a different order is the expected result. When you use a List, you expected to be able to add/insert/delete or otherwise mutate the collection, so a Reverse method that changes the order of the original list would be expected in that context.

As others have noted IEnumerable is an interface and List is a class. List implements IEnumerable.

So,

 IEnumerable<String> names = new List<String>();
 var reversedNames = names.Reverse();

gets you a second list, reversed. Whereas,

 List<String> names = new List<String>();
 names.Reverse(); 

Reverses your original list. I hope this makes sense.

Kratz
  • 4,280
  • 3
  • 32
  • 55
3

Reverse on IEnumerable<T> is part of Linq and is added as extension method (Enumerable.Reverse<T>). It was added after Reverse was implemented for List<T>.

IEnumerable<T> isn't a collection of objects either. It just tells the consumer how to get at those items.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
0

These are different methods, remember. Essentially different, with nothing common but a name.

void List.Reverse is a method of List instance only, and it does in place reversal of list or part of it.

IEnumerable Enumerable.Reverse is an extension method (btw IList also has it!) creates a new enumerable with order reversed.

Andrei
  • 55,890
  • 9
  • 87
  • 108
0

There is no such thing as IEnumerable<T>.Reverse() It's Enumerable.Reverse<T>(this IEnumerable<T>) and it's extension method from Linq applied to all IEnumerable<>.

Now that we've established when they come from, it's easy to understand why they are so different. Linq adds methods for creating "processing streams", and it's achieved by creating new instance every time.

List<T>.Reverse() is a method of List and like all it's methods (eg Add) directly modifies the instance.

Agent_L
  • 4,960
  • 28
  • 30
0

IEnumerable<T> has an underlying implementation, which could be List<T>, Hashtable<T> or something else that implements IEnumerable.

List<T> itself is the implementation, so you can directly modify that instance.

And as everyone else has mentioned, one is an extension method and part of Linq, and one is implemented directly on the type.

Stuart.Sklinar
  • 3,683
  • 4
  • 35
  • 89