Differing behavior with a Nullable type vs. a ref type re "Invalid operation" warning

Given this code:

Snippet
struct A
     {
          public object O;
     }

     class Test3
     {
          bool Has { get; set; }

          void Foo(A a1, A? a2)
          {
               Has = a1.O != null;
               if (Has)
               {
                    var v = a1.O;
               }

               Has = a2.HasValue;
               if (Has)
               {
                    var v = a2.Value;
               }
          }
     }


ReSharper will mark the "var v = a2.Value" as "Possible System.InvalidOperationException". Yet it does not do a "Possible NullReferenceException" with a1 in use above it. Is this expected?

I noticed that if I change the second "Has" to be a local bool instead of a property then the warning goes away.

Either way, the warning is unnecessary, right? While "Has" the property can change between the assignment and the 'if' following it, it seems like a false positive most of the time to flag it as a problem.

This is with 5.1.1725.5.
2 comments
Comment actions Permalink

Hello Scott,

Regarding your questions:

1. ReSharper doesn't highlight the use of a1 because a1 is of type A which
is a struct (which is a value type). A variable of a value type can never
be null.
2. At the moment ReSharper doesn't perform value analysis on non-local variables.
Therefore when you change the second Has to a local variable, ReSharper is
able to recognize that Has holds the result of a2.HasValue and uses this
knowledge when analyzing subsequent statements.

Thank you!

Andrey Serebryansky
Support Engineer
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"

Given this code:

Snippet     struct A
     {
          public
object O;      }

     class Test3
     {
          bool Has {
get; set; }
          void Foo(A
a1, A? a2)

          {

           &nbs
p;   Has = a1.O != null;

           &nbs
p;   if (Has)

           &nbs
p;   {

           &nbs
p;        var v = a1.O;

           &nbs
p;   }

           &nbs
p;   Has = a2.HasValue;

           &nbs
p;   if (Has)

           &nbs
p;   {

           &nbs
p;        var v = a2.Value;

           &nbs
p;   }

          }

     }

ReSharper will mark the "var v = a2.Value" as "Possible
System.InvalidOperationException". Yet it does not do a "Possible
NullReferenceException" with a1 in use above it. Is this expected?

I noticed that if I change the second "Has" to be a local bool instead
of a property then the warning goes away.

Either way, the warning is unnecessary, right? While "Has" the
property can change between the assignment and the 'if' following it,
it seems like a false positive most of the time to flag it as a
problem.

This is with 5.1.1725.5.

---
Original message URL:
http://devnet.jetbrains.net/message/5267236#5267236



0
Comment actions Permalink

(facepalm) yes of course. I didn't think about it being a struct, sorry. :)

Regarding the other issue, though..if Resharper is missing an ability to analyze through a particular use case, should it err on the side of a false positive or a false negative? I think it would be better to not flag something that it doesn't have the ability to really be sure about. Otherwise you could end up with lots of these cluttering up the code. Just a thought, though, this isn't a big problem.

0

Please sign in to leave a comment.