views:

150

answers:

5

I'm having a List<T> and want get the values back in reverse order. What I don't want is to reverse the list itself.

This seems like no problem at all since there's a Reverse() extension method for IEnumerable<T> which does exactly what I want.

My problem is, that there's also a Reverse() method for List<T> which reverses the list itself and returns void.

I know there are plenty of ways to traverse the list in reverse order but my question is:

How do I tell the compiler that I want to use the extension method with the same name?

var list = new List<int>(new [] {1, 2, 3});
DumpList(list.Reverse());                   // error
+8  A: 
var list = new List<int>(new [] {1, 2, 3});
DumpList((list as IEnumerable<int>).Reverse());

OR

IEnumerable<int> list = new List<int>(new [] {1, 2, 3});
DumpList(list.Reverse());
John Fisher
Ouch, of course.. time to go home :)
VVS
A: 

If you don't mind the ugliness, and you wrote the extension method, you can always call:

MyExtensions.Reverse(list);

It's still just a static method at heart. I figured this out yesterday when ReSharper went nuts and decided to rewrite half of my extension methods as calls to the static method.

As far as using the IEnumerable<T> vs. List<T>, it doesn't appear that simple. My first thought would be to use:

IEnumerable<T>.Reverse<T>(list);

But that's giving me a compiler error, and John's answer is correct for IEnumerable/List.

Chris Doggett
+2  A: 

You don't have to cast the parameter to get the right method selected... you just need to be more specific about the method.

List<int> list = new List<int>() {1, 2, 3};
DumpList(Enumerable.Reverse(list));
David B
+5  A: 

The best way to explictly bind to a particular extension method is to call it using shared method syntax. In your case, you would do that like:

DumpList(Enumerable.Reverse(list));

The problem with some of the other approaches mentioned here is that they won't always do what you want. For example, casting the list like so:

((IEnumerable)list).Reverse()

could end up calling a completely different method depending on the namespaces you have imported, or what type the calling code is defined in.

The only way to be 100% sure you bind to a particular extension method is to use the shared method syntax.

Scott Wisniewski
This is IMHO the best answer to my question so I'm giving it the credits.
VVS
Unless you type out the full namespace and name of the class, both solutions have the same potential namespace-importing problem. So neither is really better, it's just a matter of preference.
John Fisher
That case is much less likely (and, like you said, you can fully qualify the name). In general, extension methods are meant to be overloaded, and to be less preferred than instance methods. If you are trying to suppress extension method overload resolution, then it's best to not use the extension method syntax.
Scott Wisniewski
+1  A: 

This seems to work

   var stuff = new List<int>();
   var list = Enumerable.Reverse(stuff);
Dan Blair