Elad Lachmi
Elad Lachmi

Reputation: 10561

IEnumerable skip and take

I have a custom control with a data source of type IEnumerable (non-generic). Now I want to implement paging on the data source, and so I need something like Skip and Take, which List-of-T has. Right now I am using the following:

List<object> pagingList = DataSource.Cast<object>().ToList()

This can be inefficient, I'm guessing, so I'm looking for a better way to do this. Enumerating the collection, skipping elements and such with two counters might be more efficient, but it's so ugly I just don't want to do it. But maybe it's the best choice?

Upvotes: 2

Views: 10487

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1502376

Why are you calling ToList()? You can use Skip and Take without that:

IEnumerable<object> paged = DataSource.Cast<object>()
                                      .Skip(page * pageSize)
                                      .Take(pageSize);

That will save converting the whole data source to a list - but it does mean you can't skip efficiently when the source isn't an IList<T>.

Two important questions though:

  • You mention that you guess your original code is inefficient... have you measured? How big is this data, and what's its form in memory? What else are you doing with it? Is this really a bottleneck? Collect facts rather than guessing.
  • It would be easier to use your data in various ways if you had a generic data source... is that something you could achieve?

Upvotes: 11

TheEvilPenguin
TheEvilPenguin

Reputation: 5682

I don't think this will be too inefficient, given the way the LINQ extension methods are implemented. If you really wanted to, you could implement extension methods to IEnumerable for Skip() and Take(), but I don't think it's necessary.

It's a good idea to try the method where the code makes the most sense to someone reading it, and then go back and change it if you find it performs inadequately and a profiler says that this section is the culprit.

Upvotes: 1

Related Questions