Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatic Properties and Structures Don't Mix?

Kicking around some small structures while answering this post, I came across the following unexpectedly:

The following structure, using an int field is perfectly legal:

struct MyStruct {      public MyStruct ( int size )      {          this.Size = size; // <-- Legal assignment.     }       public int Size;  } 

However, the following structure, using an automatic property does not compile:

struct MyStruct {      public MyStruct ( int size )      {          this.Size = size; // <-- Compile-Time Error!     }       public int Size{get; set;} } 

The error returned is "The 'this' object cannot be used before all of its fields are assigned to". I know that this is standard procedure for a struct: the backing field for any property must be assigned directly (and not via the property's set accessor) from within the struct's constructor.

A solution is to use an explicit backing field:

struct MyStruct {      public MyStruct(int size)     {         _size = size;     }      private int _size;      public int Size     {         get { return _size; }         set { _size = value; }     } } 

(Note that VB.NET would not have this issue, because in VB.NET all fields are automatically initialized to 0/null/false when first created.)

This would seem to be an unfortunate limitation when using automatic properties with structs in C#. Thinking conceptually, I was wondering if this wouldn't be a reasonable place for there to be an exception that allows the property set accessor to be called within a struct's constructor, at least for an automatic property?

This is a minor issue, almost an edge-case, but I was wondering what others thought about this...

like image 459
Mike Rosenblum Avatar asked Jan 07 '09 14:01

Mike Rosenblum


1 Answers

From C# 6 onward: this is no longer a problem


Becore C# 6, you need to call the default constructor for this to work:

public MyStruct(int size) : this() {     Size = size; } 

A bigger problem here is that you have a mutable struct. This is never a good idea. I would make it:

public int Size { get; private set; } 

Not technically immutable, but close enough.

With recent versions of C#, you can improve on this:

public int Size { get; } 

This can now only be assigned in the constructor.

like image 154
Marc Gravell Avatar answered Sep 20 '22 01:09

Marc Gravell