{"id":8841,"date":"2022-03-16T21:35:47","date_gmt":"2022-03-16T21:35:47","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=8841"},"modified":"2022-03-16T21:35:47","modified_gmt":"2022-03-16T21:35:47","slug":"nullable-reference-types-in-c","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/nullable-reference-types-in-c\/","title":{"rendered":"Nullable reference types in C#"},"content":{"rendered":"<p>Nullable reference types are now enabled by default on projects created with Visual Studio 2022, so let&#8217;s have a quick look at them&#8230;<\/p>\n<p><strong>Enabling nullable reference type checking<\/strong><\/p>\n<p>By default nullable reference types were disabled prior to Visual Studio 2022, so would need enable them at a project or file level. Enabling in the project means adding the following to the .csproj file<\/p>\n<pre class=\"brush: csharp; highlight: [4]; title: ; notranslate\" title=\"\">\r\n&lt;PropertyGroup&gt;\r\n  &lt;OutputType&gt;Exe&lt;\/OutputType&gt;\r\n  &lt;TargetFramework&gt;net5.0&lt;\/TargetFramework&gt;\r\n  &lt;Nullable&gt;enable&lt;\/Nullable&gt;\r\n&lt;\/PropertyGroup&gt;\r\n<\/pre>\n<p>If you prefer to enable at a file level then simply add the following to the top of each file<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n#nullable enable\r\n<\/pre>\n<p><strong>Now what?<\/strong><\/p>\n<p>So once you&#8217;ve enabled nullable reference type checking, especially if on a legacy code base, be prepared for warnings such as <\/p>\n<ul>\n<li>warning CS8625: Cannot convert null literal to non-nullable reference type.<\/li>\n<li>warning CS8604: Possible null reference argument for parameter &#8216;s&#8217; in &#8216;void Program.SetName(string s)&#8217;.<\/li>\n<li>warning CS8602: Dereference of a possibly null reference.<\/li>\n<\/ul>\n<p>I&#8217;m sure there are plenty of other warnings, but you get the idea.<\/p>\n<p>Basically what we&#8217;re ask the compiler to do is tell us when we might have the potential to be passing a null into a function etc. and highlight the potential issue with a warning. In other words we now need to mark reference types as nullable so the compiler knows we&#8217;re expecting a null and in situations where we&#8217;re not using a nullable reference type we&#8217;ll be warned.<\/p>\n<p>Let&#8217;s see some example code. First off, if you default arguments to null, for example<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic void SetName(string name = null)\r\n{\r\n   \/\/ do something\r\n}\r\n<\/pre>\n<p>This will result in the warning <em>>warning CS8625: Cannot convert null literal to non-nullable reference type.<\/em>. All we need to do is tell the compiler we&#8217;re expecting a null, by making the argument nullable, i.e. add the ? to the type just like nullable value types.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic void SetName(string? name = null)\r\n{\r\n   \/\/ do something\r\n}\r\n<\/pre>\n<p>Any usage of the variable <em>name<\/em> will now expect a null check, so if we compile the following<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic void SetName(string? name = null)\r\n{\r\n   Console.WriteLine(name.Length);\r\n}\r\n<\/pre>\n<p>as you&#8217;d imagine, the compiler will issue a warning here, in this case <em>warning CS8602: Dereference of a possibly null reference.<\/em>, so obviously we have the potential of a null reference exception here, so adding a conditional check like this will fix that<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nstatic void SetName(string? name = null)\r\n{\r\n   if (name != null)\r\n   {\r\n      Console.WriteLine(name.Length);\r\n   }\r\n}\r\n<\/pre>\n<p>In some situations you may in fact know a variable\/argument is not null &#8211; in TypeScript it&#8217;s not unusual to find the transpiler getting a little confused in which case we use the <em>null-forgiving operator<\/em> simply an !, so whilst the <em>SetName<\/em> method, as it stands ofcourse can be null, what if we remove the optional argument and expect all callers of the <em>SetName<\/em> method &#8211; for example maybe it&#8217;s a private method and we know each caller must check for null first anyway, then we use the following<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nstatic void SetName(string? name)\r\n{\r\n   Console.WriteLine(name!.Length);\r\n}\r\n<\/pre>\n<p>We&#8217;re basically saying, by using <em>name!.<\/em> we know the value is not null. This example is a little contrived because we could just change the <em>string?<\/em> to <em>string<\/em> and not require the !, but you get the idea.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nullable reference types are now enabled by default on projects created with Visual Studio 2022, so let&#8217;s have a quick look at them&#8230; Enabling nullable reference type checking By default nullable reference types were disabled prior to Visual Studio 2022, so would need enable them at a project or file level. Enabling in the project [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-8841","post","type-post","status-publish","format-standard","hentry","category-c"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8841","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=8841"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8841\/revisions"}],"predecessor-version":[{"id":9298,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/8841\/revisions\/9298"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=8841"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=8841"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=8841"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}