2

I am getting a ReSharper (2018.1) warning for Possible 'System.NullReferenceException' when I check for null implicitly with if (obj) instead of if (obj ! = null).

For example:

using JetBrains.Annotations;
using UnityEngine.UI;

public class CanBeNullTest : MonoBehaviour
{
    [CanBeNull] public Button Button { get; set; }

    private void EnableButton_explicitCheck()
    {
        if (Button != null) Button.enabled = true;
    }

    private void EnableButton_implicitCheck()
    {
        if (Button) Button.enabled = true;
    }

    //private void EnableButton_cSharp6()
    //{
    //    // null propagating operator is not available in C# 4
    //    Button?.enabled = true;
    //}
}

Only the implicit null check shows the ReSharper warning:

ReSharper-null-check-warning

I looked at the ReSharper page for "Why is ReSharper suggesting this" and the links there, but I couldn't find an explanation for this.

Is this a ReSharper limitation? Or is it incorrect or bad style to check for null implicitly?

sonnyb
  • 3,194
  • 2
  • 32
  • 42
  • 4
    So the Button class has an implicit conversion from Button to `bool`? Why should resharper care about that? There is no convention that you can use C# like javascript. – Tim Schmelter Aug 30 '18 at 15:54
  • @TimSchmelter oh I see, I was confused and I thought the implicit conversion to bool was a built-in C# feature. Thanks. If you want to post your comment as an answer I'll mark it as accepted. – sonnyb Aug 30 '18 at 16:46
  • 1
    Here's a relevant discussion on Unity forums: [Why does Unity implicitly cast any MonoBehavior object to a Boolean](https://forum.unity.com/threads/why-does-unity-implicitly-cast-any-monobehavior-object-to-a-boolean.390488/) – sonnyb Aug 30 '18 at 16:57

2 Answers2

2

Although it doesn't actually produce a NullReferenceException, because your Button can be null and the if statement triggers an implicit conversion to boolean that produces the NullReferenceException, it is still valid warning in general.

Something similar in Java, Check if null Boolean is true results in exception

If you don't like extra null checks, you may be able to do the C# equivalent of the following Java code,

if (Boolean.TRUE.equals(value)) {...}
Won Jun Bae
  • 5,140
  • 6
  • 43
  • 49
  • 1
    I tested the code I posted, and it doesn't actually produce a `NullReferenceException`. However, I see how it is a valid warning for ReSharper to say that there is a possible `NullReferenceException` when the object is being implicitly converted to bool. Note: Unity Object's implicit conversion to bool: `public static implicit operator bool(UnityEngine.Object exists) { return !UnityEngine.Object.CompareBaseObjects(exists, (UnityEngine.Object) null); }` - it's a static call to a helper method that does a `== null` check (and some other checks that seem related to Unity's == operator override.) – sonnyb Aug 31 '18 at 11:20
1

The if (Button) involves an implicit conversion to bool, which doesn't produce a NullReferenceException in this case, but it is a valid warning in general.

sonnyb
  • 3,194
  • 2
  • 32
  • 42