LINQ with Skip and Take
Asked Answered
V

1

27

I used the below code to take some items from IEnumerable, but it is always returning the source as null and count as 0 and actually there are items exists in IEnumerable

private void GetItemsPrice(IEnumerable<Item> items, int customerNumber)
{
    var a = items.Skip(2).Take(5);
}

When i try to access a it has count 0. Anything goes wrong here?

enter image description here

Vienna answered 13/3, 2013 at 12:53 Comment(13)
How many items are in the collection initially?Leporine
No i have something more, but for my question this alone enoughVienna
What does items contain?Gossipy
@GrantThomas, it contain 102 itemsVienna
What do you mean by "returning the source as null"? And if a.Count() returns 0, then basically there were at most 2 elements in items. If you think there were 102 items, I suspect your diagnostics are incorrect.Broadtail
@DarrenDavies, it is a object collections which contains itemid and itemnameVienna
Downvoters care to comment, whats wrong with my question ?Vienna
And what does the output of dumping items to the immediate window look like?Star
@JonSkeet, pls check my attachment and it taken from immediate windowVienna
You still don't seem to be Enumerating your collection. IEnumrables are lazy loaded and won't do what you want until you tell them.Neuralgia
@SSS: There's no indication from the screenshot that items.Count() is more than 2.Broadtail
@JonSkeet, pls check my updated screenshot and i have added count in itVienna
@SSS: Ah... lazyberezovsky has discovered the issue. This is why you shouldn't usually try to interpret the values of private members you don't understand. If you'd called a.Count() you'd have seen something very different.Broadtail
I
45

Remember, that variable a in your code is a query itself. It is not result of query execution. When you are using Immediate Window to watch query (actually that relates to queries which have deferred execution otherwise you will have results instead of query), it will always show

{System.Linq.Enumerable.TakeIterator<int>}
    count: 0
    source: null

You can verify that with this code, which obviously has enough items:

int[] items = { 1, 2, 3, 4, 5, 6, 7 };
var a = items.Skip(2).Take(3);

So, you should execute your query to see results of query execution. Write in Immediate Window:

a.ToList()

And you will see results of query execution:

Count = 3
    [0]: 3
    [1]: 4
    [2]: 5
Inchoation answered 13/3, 2013 at 13:12 Comment(6)
that's it. msdn.microsoft.com/en-us/library/bb503062.aspx "The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach "Stebbins
@Stebbins yes that is what simply called as query: an object that stores all the information that is required to perform the actionInchoation
Thanks for clarification I need to pass this as parameter items.Skip(2).Take(5)to another method. Do i need to use .ToList() to pass this as parameter?Vienna
As I noted in another comment: this is why you shouldn't use the debugger to show you fields you don't know the meaning of, and then assume you do understand the meaning...Broadtail
@SSS: Well you might want to. It depends. But you need to understand that the only reason you're seeing 0 is because you're looking at a field which is an implementation detail you wouldn't normally be able to observe. It's not the length of the sequence.Broadtail
@SSS as Jon stated, it depends. If you will return a, then query will be executed by caller later (it is not always possible). If you will return result of query execution by adding ToList() then caller will work with objects in memory (that could be problem if your query gets items from database).Inchoation

© 2022 - 2024 — McMap. All rights reserved.