hoangduit / google-gdata

Automatically exported from code.google.com/p/google-gdata
0 stars 0 forks source link

IEnumerable<Contact> Object Doesn't "Reset" As Expected #421

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
On the GData .NET Library 1.6.0.0, Windows 7 x64, Visual Studio 2010, targeting 
the .NET Framework 4.0.

I'll preface this by saying that maybe I'm not entirely sure whether this is a 
bug, or if I'm just not as well-versed on IEnumerable<T> collections as I 
should be.

What steps will reproduce the problem?
1. Create RequestSettings object, with AutoPaging set to true.
2. Feed that to a ContactsRequest constructor to get a new CR object.
3. Call the CR's GetContacts() method, and assign the return value to a local 
Feed<Contact> object.
4. Iterate over your Feed<Contact>.Entries collection using a foreach 
statement, but stop about halfway through. I'm doing this by doing something 
like:
foreach (Contact c in _contactsFeed.Entries)
  if (c.AtomEntry.Id.AbsoluteUri == DesiredEntryUri)
    return c;
6. Now, again, iterate over the Feed<Contact>.Entries collection. Notice the 
StartIndex when you begin to iterate this time. It'll be more than 1 (unless 
the contact you found previously was the 1st or last in the collection). 
Because of this there's a bad-to-certain chance that you'll never find the 
Contact your looking for, because the .Entries collection never goes back to a 
StartIndex of 1 (1-based) until you iterate over the collection COMPLETELY. So, 
for instance if I do this instead of what was done above:
Contact returnContact = null
foreach (Contact c in _contactsFeed.Entries)
  if (c.AtomEntry.Id.AbsoluteUri == DesiredEntryUri)
    returnContact = c;
return returnContact;

Everything works just fine, because I don't break or return once I've found the 
Contact I want, and I finishing iterating over the collection. 

So I'm thinking that it'd be nice if each time I go to iterate over the Entries 
collection, that the Feed gives me the Entry at position 0 instead of where I 
last left off.

What is the expected output? What do you see instead?
Expected: IEnumerable Entries starts over when I iterate over it each time.
What Happens: Entries appears to start off where I last left the collection.

Please provide any additional information below.
Hopefully this isn't just me not understanding the objects in use here. If 
there's any additional information I can provide, please don't hesitate to ask. 
Or if this is me being a little slow, feel free to give me a smack up-side the 
head to get me thinking! ;)

Original issue reported on code.google.com by grkaiser@gmail.com on 30 Aug 2010 at 11:38

GoogleCodeExporter commented 9 years ago
Aaaaand I skipped from 4 to 6 in my steps to reproduce. <sigh> Been a long day.

Original comment by grkaiser@gmail.com on 30 Aug 2010 at 11:47

GoogleCodeExporter commented 9 years ago
Hey grkaiser,

From my understanding, the entries property of the Feed class is not designed 
to be iterated over more than once. You should be able to use 
_contactsFeed.Entries.ToList to save the list of contacts to a List(Of 
Contacts).  You can then use the List to iterate over your contacts more than 
once.  You can also use the List's Find method to find what your're looking 
for.  I'm not so quick with the c# (don't like the semicolons), but below is a 
quick and dirty example in VB:

Public Class MyClass
    Private _UriToFind As String

    Public Sub GetContacts()
        ''''
        ''''
        'Get Feed
        ''''
        ''''

        Dim feed As Google.GData.Client.Feed(Of Google.Contacts.Contact)
        Dim listOfContacts As List(Of Google.Contacts.Contact) = feed.Entries.ToList

        Dim foundContact As Google.Contacts.Contact
        _UriToFind = "Your Uri"
        foundContact = listOfContacts.Find(AddressOf FindContactWithUri)
    End Sub

    Private Function FindContactWithUri(ByVal contact As Google.Contacts.Contact) As Boolean
        Dim result As Boolean = False
        If contact.ContactEntry.Id.AbsoluteUri = _UriToFind Then
            result = True
        End If
        Return result
    End Function
End Class

Original comment by edwin.la...@gmail.com on 31 Aug 2010 at 3:42

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
@edwin.landy: That's true, I can use the Entries collection to create my own 
collection and then everything seems to play nicely.

It turns out that if I take a look at Feed<T>'s Entries property the summary in 
trunk/clients/cs/src/core/feedmodel.cs states:
"Note that you should cache the entries returned in a list of your own if you 
want to access them more than once, as this one does no caching on it's own."

Three things about that though. 
#1 that summary is commented out, so it'll never show up anywhere and be 
helpful. i.e. It won't show up in the pop-up's in VS.
#2 the documentation on the library makes absolutely no mention of caching the 
results. 
#3 I don't believe that that's the standard or correct behavior for an 
IEnumerable<T> collection. I understand, though, that since the property is 
dealing with issues with auto-paging and getting results from the server that 
it might work differently than usual collections. 

I still think that this is something that deserves a big exclamation mark next 
to it to ensure that the consuming code does cache the results, because the 
behavior is as confusing as all get-out.

Original comment by grkaiser@gmail.com on 1 Sep 2010 at 9:55

GoogleCodeExporter commented 9 years ago

There are a lot of places in the code where the comments of the base class 
don't show through to the classes that actually get used.  Maybe that's 
something that we in the community can work on?  Can a committer let us know 
the best way we can get this done?

Maybe Frank can chime in on why there's no caching.  It's probably got 
something to do with the way the feed class automatically pages through the 
'next' batch of 100 results.

Original comment by edwin.la...@gmail.com on 2 Sep 2010 at 12:20

GoogleCodeExporter commented 9 years ago
That's pretty much it. Considering that results are not guaranteed to be 
identical between queries in google services (heck, the whole world can add 
videos to youtube, e.g.) coming up with a simple caching scheme is pretty much 
impossible, so i left that to the application developer, as the app developer 
is the best one to judge what to cache, and what not. 

That the long, and hopefully helpful comment is not showing up is a bug/problem 
with the documentation system. I need to change that to follow the stupid /// 
convention. You would hope that longer comments like this would still be parsed 
correctly, but, nope.... 

Original comment by frank%ma...@gtempaccount.com on 7 Sep 2010 at 10:58

GoogleCodeExporter commented 9 years ago

Original comment by ccherub...@google.com on 29 Jul 2011 at 10:08