Why can't I call OrderBy on a class that extends List?

I have a Deck class containing a Shuffle method.

I am working on Deck refactoring to extend the List<Card> , instead of having List<Card> Cards as a property. However, while Cards.OrderBy (a => Guid.NewGuid ()) worked, OrderBy (a => Guid.NewGuid ()) does not:

Error CS0103: The name 'OrderBy' does not exist in the current context (CS0103)

Why is this not working?

+2
inheritance c # linq extension-methods
Jan 27
source share
3 answers

Add this to the top of OrderBy , as in

 this.OrderBy(a => Guid.NewGuid()); // a random ordering 

OrderBy is an extension method on IEnumerable<T> and is not a public method on List<T> . If you type OrderBy without context, the compiler will look for an instance or static method named OrderBy . Only if the prefix OrderBy with an instance of IEnumerable<T> , the compiler will find OrderBy . For Deck : List<Card> and List<Card> : IEnumerable<Card> using the this (link to the current instance) will provide the compiler with the context needed to find the Enumerable.OrderBy method.

In the public API, it is considered bad practice to inherit from List<T> . First, List<T> not intended to be inherited, and probably should have been sealed ; too late for that now. In general, you should approve composition over inheritance when using framework classes.

+8
Jan 27
source share

OrderBy is an extension method, so it can only be used with a classifier of type IEnumerable<T> .

You need to write this.OrderBy . ( this is a classifier of type Deck , which indirectly inherits IEnumerable<Card> )

Note that OrderBy not in-place sorting; if you want to sort an existing instance, call Sort((a, b) => 2 - 2 * rand.Next(0, 1)) , where rand is an instance of the Random class.




Note : bad practice for List<T> inheritance . Instead, you should inherit System.Collections.ObjectModel.Collection<T> .

+3
Jan 27 '10 at 1:50
source share

OrderBy is not a method on List<T> - rather, it is defined as an extension method of Enumerable.OrderBy .

Since this is not a class method, you need to make the compiler see this. You can do this by calling:

this.OrderBy (a => Guid.NewGuid ());

However, I recommend revising your approach here. Subclassing List<T> is a bad idea - it is much better to implement IList<T> by encapsulating your List<T> instance. List<T> should be an implementation detail, not part of the API itself.

+1
Jan 27 '10 at 1:52
source share



All Articles