21

The code:

Contact cnt1 = new Contact(LastName = 'test');
Contact cnt2;

System.debug(cnt1.LastName);                   // <-- as expected: 'test'
System.debug(cnt2?.LastName);                  // <-- as expected: null

System.debug(cnt1.LastName != cnt2?.LastName); // <-- as NOT expected: false

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SafeNavigationOperator.htm

Is anybody able to explain this behavior?

Added later:

and same behavior for user defined classes (not only for SObject):

class Test {
    Test(String field) {
        this.field = field;
    }
    public String field;
}

Test t1 = new Test('test');
Test t2;

System.debug(t1.field);               // <-- as expected: 'test'
System.debug(t2?.field);              // <-- as expected: null

System.debug(t1.field != t2?.field);  // <-- as NOT expected: false
System.debug(t1.field == t2?.field);  // <-- as NOT expected: true
System.debug(t2?.field != t1.field);  // <-- as expected: true

System.debug(String.valueOf(cnt1.field) != String.valueOf(cnt2?.field)); // also false
System.debug('' + cnt1.field != '' + cnt2?.field);                       // as expected - true

interesting that when we use operator '==' we have result true... What system try to compare in this lines?

In addition, System.assertEquals and System.assertNotEquals have compilation errors when trying to use this operator.

class B {
    string field = 'Test';
}
B b1 = new B(), b2;
//System.TypeException: Comparison arguments must be compatible types: String, Boolean
System.assertEquals(true, b1.field != b2?.field);
10
  • 1
    Interestingly, it works as expected if you swap the order cnt2?.LastName != cnt1.LastName. Oct 20, 2020 at 13:14
  • 2
    This is a brand new operator, so there's bound to be a few glitches. I'll let someone know. You should submit a case with support.
    – sfdcfox
    Oct 20, 2020 at 13:19
  • @KrisGoncalves: Also works irrespective of ordering, when we store the LastName properties to a string variables and use string variable for comparison. Looks like a bug, JavaScript doesn't have this behavior.
    – Raul
    Oct 20, 2020 at 13:19
  • @krisGonsales, yes, but why it not works in opposite order? i try to understand how comparison can be evaluated to have result equal to false and unable to imagine this - only have idea that comparison not executed at all and for some reason returned false. but why? Oct 21, 2020 at 4:17
  • 1
    I added one additional bug example (CompileFail: types must be compatible, string, boolean) I found while logging this case. Engineering is on it.
    – sfdcfox
    Oct 28, 2020 at 21:52

2 Answers 2

12

Somehow it works only in the first place of comparison operator (or when storing values to variables):

System.debug(cnt2?.LastName != cnt1.LastName); 

Parentheses also does not help. Out of curiosity I have tried to compare both sides with safe navigation operators:

Contact cnt2;
Contact cnt3;
System.debug(cnt2?.LastName != cnt3?.LastName); 

But this throws FATAL_ERROR Internal Salesforce.com Error in Developer Console.

I think, that replacement mechanism does not work properly at this time and it is Salesforce bug.

5
  • 13
    I've brought this to Chris Peterson's attention. We should have a more official answer today sometime.
    – sfdcfox
    Oct 20, 2020 at 13:44
  • @sfdcfox Seems that nobody will comment this from the SF side. Oct 27, 2020 at 15:51
  • 3
    I have logged a case as a Premier+ Support customer, we should have feedback shortly. I appreciate you following up with me.
    – sfdcfox
    Oct 27, 2020 at 16:55
  • 2
    @sfdcfox Was there any update on your case with the Premier+ support? Just curious to know about any new information for this problem.
    – arut
    Nov 6, 2020 at 7:00
  • @arut See my answer.
    – sfdcfox
    Nov 19, 2020 at 18:21
7

Edit

All of the issues in this question now appear to be resolved. Some tests that were previously reporting inverted results (e.g. comparisons that returned true instead of false) are now fixed, comparison types are now fixed, user classes no longer exhibit weird behaviors, the compilation errors and Internal Server Errors all appear to be fixed, etc. I will continue to experiment with this operator, as I have a lot of things I plan on patching with this operator, but it now seems to be fixed.


I have been in contact with Premier Support, R&D has confirmed the bug, and a patch is planned for December 3rd, 2020, 5:00PM PST. This should resolve the errors with this operator. I will follow up with this over the weekend of December 5th, 2020 to confirm that the behavior is indeed fixed, and take any further action if necessary.

4
  • thanks for your efforts!
    – Raul
    Nov 19, 2020 at 19:23
  • +1 Thanks for the update.
    – arut
    Nov 20, 2020 at 3:36
  • 1
    @sfdcfox - was this indeed fixed? Dec 14, 2020 at 15:24
  • @AlejandroFlores Thanks for reminding me. I've edited this answer. It does appear that all of the various errors, compilation errors, runtime errors, and inverted comparison results are all fixed. I'll update this answer if I find any remaining bugs, but it seems to be solid now.
    – sfdcfox
    Dec 14, 2020 at 16:21

You must log in to answer this question.

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