{"id":10089,"date":"2023-09-30T09:33:56","date_gmt":"2023-09-30T09:33:56","guid":{"rendered":"https:\/\/putridparrot.com\/blog\/?p=10089"},"modified":"2023-11-22T00:15:48","modified_gmt":"2023-11-22T00:15:48","slug":"primary-constructors-are-coming-in-c-12-to-classes-and-structs","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/primary-constructors-are-coming-in-c-12-to-classes-and-structs\/","title":{"rendered":"Primary Constructors are coming in C# 12 to classes and structs"},"content":{"rendered":"<p>Available as part of Visual Studio 17.6 preview 2. C# will be adding primary constructors.<\/p>\n<p>Primary constructors already exist (as such) for records, but can be added to classes and structs, so the syntax<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class Person(string firstName, string lastName, int age);\r\n<\/pre>\n<p>will be equivalent to <\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class Person\r\n{\r\n   private readonly string firstName;\r\n   private readonly string lastName;\r\n   private readonly int age;\r\n\r\n   public Person(string firstName, string lastName, int age)\r\n   {\r\n      this.firstName = firstName;\r\n      this.lastName = lastName;\r\n      this.age = age;\r\n   }\r\n}\r\n<\/pre>\n<p>By using a primary constructor the compiler will no longer generate a default (parameterless) constructor. You can ofcourse add your own but you&#8217;ll then need to call the primary constructor, for example<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nclass Person(string firstName, string lastName, int age)\r\n{\r\n   public Person() :\r\n      this(&quot;&quot;, &quot;&quot;, 0)\r\n   {\r\n   }\r\n}\r\n<\/pre>\n<p>An obvious syntactic difference between a class\/struct primary constructor and a record&#8217;s is the record parameters are public, so we would tend to use property (Pascal Case) naming conventions and the properties are exposed as public readonly properties. For the class\/struct these parameters map to private fields hence we use camel Case (if following the standards). <\/p>\n<p>Note, you cannot access them using <em>this.firstName<\/em>. This statement might seem slightly confusing because whilst you cannot, for example, write the following<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic Person() : \r\n   this(&quot;&quot;, &quot;&quot;, 0)\r\n{\r\n   \/\/ this will not even compile\r\n   this.firstName = &quot;Test&quot;;\r\n   \/\/ also will not compile\r\n   firstName = &quot;Test&quot;;\r\n}\r\n<\/pre>\n<p>You can do things like the following<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nclass Person(string firstName, string lastName, int age)\r\n{\r\n    public string FirstName\r\n    {\r\n        get =&gt; firstName;\r\n        set =&gt; firstName = value;\r\n    }\r\n\r\n    public override string ToString() =&gt; $&quot;{firstName} {lastName} {age}&quot;;\r\n}\r\n<\/pre>\n<p>Essentially your primary constructor parameters are not available in overloaded constructors or using the <em>this.<\/em> syntax.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Available as part of Visual Studio 17.6 preview 2. C# will be adding primary constructors. Primary constructors already exist (as such) for records, but can be added to classes and structs, so the syntax public class Person(string firstName, string lastName, int age); will be equivalent to public class Person { private readonly string firstName; private [&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-10089","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\/10089","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=10089"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/10089\/revisions"}],"predecessor-version":[{"id":10180,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/10089\/revisions\/10180"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=10089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=10089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=10089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}