{"id":1273,"date":"2017-12-17T17:23:23","date_gmt":"2017-12-17T15:23:23","guid":{"rendered":"http:\/\/tpodolak.com\/blog\/?p=1273"},"modified":"2017-12-17T17:23:23","modified_gmt":"2017-12-17T15:23:23","slug":"null-propagation-operator-conditional-statements","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2017\/12\/17\/null-propagation-operator-conditional-statements\/","title":{"rendered":"Null-propagation operator and conditional statements"},"content":{"rendered":"<p>This post is just a quick reminder for me to put a bit more attention to conditional statements combined with a null-propagation operator. Nothing too fancy but I tend to overlook this when doing code review.<br \/>\nStarting from C# 6 we can simplify accessing members of an object which might be <i>null<\/i> thanks to <i>?.<\/i> operator. For my perspective it is particularly useful within <i>if<\/i> statements, however, you have to be aware of how compiler rewrites the code under the hood otherwise, it is easy to introduce a bug. Consider following scenario<\/p>\n<pre lang=\"csharp\">\r\npublic Flight GetFirstPossibleFlight(Availability availability)\r\n{\r\n    if (availability.Flights?.Any() == false)\r\n    {\r\n       return null;\r\n    }\r\n            \r\n    \/\/ more magic in here\r\n     return availability.Flights.First();\r\n}\r\n<\/pre>\n<p>At a glance everything seems to be ok, we make sure that <i>Flight<\/i> collection is not accessed if it is <i>null<\/i>, however simple test shows that this method has a bug.<\/p>\n<pre lang=\"csharp>\r\n[Fact]\r\npublic void GetFirstPossibleFlight_ReturnsNull_WhenFlightsCollectionIsEmpty()\r\n{\r\n    var availability = new Availability\r\n    {\r\n        Flights = null\r\n    };\r\n            \r\n    var subject = new AvailabilityScanner();\r\n\r\n    var result = subject.GetFirstPossibleFlight(availability);\r\n\r\n    result.Should().BeNull();\r\n}\r\n<\/pre>\n<p><a href=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/12\/null-propagation-operator-and-conditional-statements\/FailedTest.png\"><img decoding=\"async\" src=\"\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/12\/null-propagation-operator-and-conditional-statements\/FailedTest.png\" alt=\"\" height=\"375\" class=\"aligncenter size-full wp-image-1274\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/12\/null-propagation-operator-and-conditional-statements\/FailedTest.png 1182w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/12\/null-propagation-operator-and-conditional-statements\/FailedTest-150x48.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/12\/null-propagation-operator-and-conditional-statements\/FailedTest-300x95.png 300w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2017\/12\/null-propagation-operator-and-conditional-statements\/FailedTest-1024x325.png 1024w\" sizes=\"(max-width: 1182px) 100vw, 1182px\" \/><\/a><br \/>\nWe protected the code from <i>NullReferenceException<\/i> in <i>if<\/i> statement, however we failed on the return statement. This happens because our original code is rewritten by compiler <a href=\"https:\/\/sharplab.io\/#v2:CYLg1APgAgDABFAjAFgNwFgBQsGIHQAyAlgHYCOG2AzAgExwCCAbgIZEA2LARh0QC4BPAMoBjFiRIBTAE5YA3ljhKENAGLsiAcwAWfOAHFJfVUWkBnPgAUA9mbNEu7Seq26AFMzaceGwXBasHNy8ggCUisoKmMoxcEQAZnBuAV7BvgJ4Ljp8ZgD8eAwkAm6hcAC8ZXDxLOxmkuHRsUpRTU1QAOxwJACu7OyUrXAAvhGDSqNjAPSTcAC21tKScyyaRCJxJHDaMpITMR3+gd4hGVm6ZpmmFiUDyiOY91hQNFD0Z3zyWI\/UdIxHafwBJ9GkpnnBiBYADzvAB8cHeZjgcjgmiMqDgdT46PuQyAA=\">as follows<\/a><\/p>\n<pre lang=\"csharp\">\r\npublic Flight GetFirstPossibleFlight(Availability availability)\r\n{\r\n    List<Flight> expr_07 = availability.Flights;\r\n    bool flag = expr_07 != null && !expr_07.Any<Flight>();\r\n    Flight result;\r\n    if (flag)\r\n    {\r\n        result = null;\r\n    }\r\n    else\r\n    {\r\n        result = availability.Flights.First<Flight>();\r\n    }\r\n    return result;\r\n}\r\n<\/pre>\n<p>Now it is clearly visible that we have to satisfy both of the conditions in order to return <i>null<\/i>. Fortunately, you still can use one-liner and have a bug-free code, the one thing which is needed is an additional null-coalescing operator in the <i>if<\/i> statement.<\/p>\n<pre lang=\"csharp\">\r\npublic Flight GetFirstPossibleFlight(Availability availability)\r\n{            \r\n    if ((availability.Flights?.Any() ?? false) == false)\r\n    {\r\n        return null;\r\n    }\r\n            \r\n    \/\/ more magic in here\r\n    return availability.Flights.First();\r\n}\r\n<\/pre>\n<p>Now the compiler will rewrite the code <a href=\"https:\/\/sharplab.io\/#v2:CYLg1APgAgDABFAjAFgNwFgBQsGIHQAyAlgHYCOG2AzAgExwCCAbgIZEA2LARh0QC4BPAMoBjFiRIBTAE5YA3ljhKENAGLsiAcwAWfOAHFJfVUWkBnPgAUA9mbNEu7Seq26AFMzaceGwXBasHNy8ggCUisoKmMoxcEQAZnBubgFewb4CeC46fGYA\/HgMJAJuoXB5eXDxLOxmkmUAvA1VNXXh0bGdUZ09ylAA7HAkAK7s7JS9MQC+EZNws5MA9ItwALbW0pJrLJpEInEkcNoykgu9A\/6B3iGZ2bpmWaYWpRPKM5jvWFA0UPR3fPIsJ9qHRGFd0vwBICOkpvnBiBYADz\/AB8cH+ZjgcjgmiMqDgdT4+PeUyAA=\">in a following way<\/a><\/p>\n<pre lang=\"csharp\">\r\npublic Flight GetFirstPossibleFlight(Availability availability)\r\n{\r\n    List<Flight> expr_07 = availability.Flights;\r\n    bool flag = expr_07 == null || !expr_07.Any<Flight>();\r\n    Flight result;\r\n    if (flag)\r\n    {\r\n        result = null;\r\n    }\r\n    else\r\n    {\r\n        result = availability.Flights.First<Flight>();\r\n    }\r\n    return result;\r\n}\r\n<\/pre>\n<p>Notice that <i>AND<\/i> operator was replaced with <i>OR<\/i> operator, resulting in code safe from <i>NullReferenceException<\/i>.<br \/>\nSource code for this post can be found <a href=\"https:\/\/github.com\/tpodolak\/Blog\/tree\/master\/NullPropagationOperatorAndIfStatements\">here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post is just a quick reminder for me to put a bit more attention to conditional statements combined with a null-propagation operator. Nothing too fancy but I tend to overlook this when doing code review. Starting from C# 6 we can simplify accessing members of an object which might be null thanks to ?. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[159],"class_list":["post-1273","post","type-post","status-publish","format-standard","hentry","category-c","tag-c"],"_links":{"self":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/1273","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/comments?post=1273"}],"version-history":[{"count":13,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/1273\/revisions"}],"predecessor-version":[{"id":1287,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/1273\/revisions\/1287"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=1273"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=1273"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=1273"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}