26

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

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • 4
    How many items _are_ in the collection initially? – Grant Thomas Mar 13 '13 at 12:54
  • No i have something more, but for my question this alone enough –  Mar 13 '13 at 12:55
  • What does items contain? – Darren Mar 13 '13 at 12:55
  • @GrantThomas, it contain 102 items –  Mar 13 '13 at 12:56
  • 1
    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. – Jon Skeet Mar 13 '13 at 12:56
  • @DarrenDavies, it is a object collections which contains `itemid` and `itemname` –  Mar 13 '13 at 12:57
  • Downvoters care to comment, whats wrong with my question ? –  Mar 13 '13 at 13:00
  • And what does the output of dumping `items` to the immediate window look like? – Jonas Høgh Mar 13 '13 at 13:00
  • @JonSkeet, pls check my attachment and it taken from immediate window –  Mar 13 '13 at 13:01
  • 1
    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. – Thomas Lindvall Mar 13 '13 at 13:06
  • 2
    @SSS: There's no indication from the screenshot that `items.Count()` is more than 2. – Jon Skeet Mar 13 '13 at 13:09
  • @JonSkeet, pls check my updated screenshot and i have added count in it –  Mar 13 '13 at 13:17
  • @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. – Jon Skeet Mar 13 '13 at 13:23

1 Answers1

41

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
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • 2
    that's it. http://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 " – Xaruth Mar 13 '13 at 13:14
  • @Xaruth yes that is what simply called as *query*: an object that stores all the information that is required to perform the action – Sergey Berezovskiy Mar 13 '13 at 13:15
  • 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? –  Mar 13 '13 at 13:24
  • 1
    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... – Jon Skeet Mar 13 '13 at 13:24
  • 1
    @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. – Jon Skeet Mar 13 '13 at 13:25
  • @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). – Sergey Berezovskiy Mar 13 '13 at 13:31