Is there a way to retrieve the list of fields in a specific instance of an sObject?
That is, not all the fields that are defined on that sObject, but those fields which are populated on a particular instance of it in code.
Explanation of the problem
I can create an instance of account as follows
Account myAcc = new Account(firstname = 'Doug', billingCity=null);
If I do a System.debug I can see that this is an account, with values for the two fields which I have specified.
System.debug(myAcc); // This outputs Account:{BillingCity=null, FirstName=Doug}
Now if I am working with that variable myAcc, how do I know that it has values for firstname and billingCity, but not for (say) personemail?
I can retrieve the value of a given field by name. This isn't good enough as I can't tell which fields are null because they were explicitly made so (in this example billingCity) or null because they are not specified.
System.debug(myAcc.get('firstname')); // This outputs Doug
System.debug(myAcc.get('billingcity')); // This outputs null, it has been set to null
System.debug(myAcc.get('personemail')); // This also outputs null, but it is not being set
This is important because if I issue an update on myAcc it updates only the explicitly set fields. So in this case it an update would set the firstname to Doug, would blank out the billingcity, but would leave the personemail untouched.
This matters to me as I am trying to merge two or more of them in code before doing an update.
Looking for a solution
Given the get syntax that you can use on an sObject, I was hoping I could get some map or list like behaviour out of it, but I haven't had any luck.
// Can we get a list of the fields that are in the instance?
System.debug(myAcc.keyset()); // Method does not exist or incorrect signature: [SOBJECT:Account].keyset()
// Can we retrieve something by index rather than name, and iterate?
System.debug(myAcc.get(0)); // Method does not exist or incorrect signature: [SOBJECT:Account].get(Integer)
I could serialize it into JSON, and then parse through it but that's pretty horrible and heavyweight.
Is there a nice easy solution to finding which fields are present in an instance of an sObject?