4

Found this in a great post on salesforce collections (http://peterknolle.com/collections-eggstravaganza/). Can anyone explain what is going on here that this isn't true?

   Account acct = [
        Select 
            Id, Name,
            (Select Name From Contacts)
        From Account
        Limit 1
    ];

    System.assert(acct.Contacts === acct.Contacts); // fails assertion

1 Answer 1

9

This is actually explained briefly in the article you linked to, but I'm assuming you want an expanded answer.

When returning a nested collection (as Contacts is in this example), Apex returns a defensive copy of the collection, rather than the actual collection. To simplify that further, each time you call acct.Contacts the Contacts list is constructed fresh and will occupy a different location in memory.

Here is a simple example of how you could achieve this in your own class:

public class DefensiveListExample
{
    private List<Contact> internalContacts;

    public List<Contact> Contacts 
    { 
        get 
        { 
            return new List<Contact>(internalContacts); 
        } 
    }
}

Generally this type of behaviour is provided to prevent you violating invariants of classes and keep control of the collection within the class itself, or in languages like C# can be used to provide a read-only version of a collection.

The === compares the location in memory of the two compared objects, as opposed to the == which compares the object types and fields of the objects.

Therefore, because the returned value of each call to acc.Contacts resides in a different place in memory, acct.Contacts === acct.Contacts is false.

2
  • Thanks, yes it wasn't clear to me from the explanation in the article exactly what was going on behind the scenes. This clears it up! Also, there is no way for us to recreate that exact structure that results from the query/subquery correct? A list Accounts containing a list of their Contacts without creating our own classes that mimic those.
    – Phil B
    Commented Apr 15, 2014 at 19:37
  • 1
    You can do a query of Accounts with Contacts - but should ask how to do that in a separate question posted here. Commented Apr 15, 2014 at 23:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .