4

The following code suggests I cannot use implicit properties with a struct:

public struct LimitfailureRecord
{
   public LimitfailureRecord(string sampleCode)
   {
      SampleCode = sampleCode;
   }

   public string SampleCode {get; set;}
   {
   }
}

It fails to compile, with the error message

"Backing field for automatically implemented property 'blahblah.LimitfailureRecord.SampleCode' must be fully assigned before control is returned to the caller. Consider calling the default constructor from a constructor initializer."

If I change the struct to a class it's fine. What do I need to do to make this work as a struct? I'd rather not go to the lengths of backing fields (this is a heavily stripped down version of the real code) if I can avoid it.

Brian
  • 5,069
  • 7
  • 37
  • 47
haughtonomous
  • 4,602
  • 11
  • 34
  • 52
  • Dup: [C#: Struct Constructor: “fields must be fully assigned ..."](http://stackoverflow.com/questions/2534960/c-struct-constructor-fields-must-be-fully-assigned-before-control-is-returne) – Tim Schmelter Apr 12 '13 at 15:48

3 Answers3

5

With structs you have to call the default constructor in all other constructors:

public LimitfailureRecord(string sampleCode) : this()
{
    SampleCode = sampleCode;
}
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
2

Use a constructor chaining like so:

public LimitfailureRecord(string sampleCode)
    : this()
{
    ...
}

The reason is the auto-implemented property introduces a (generated) instance field for backing, as described. All instance fields must be assigned to in an instance constructor of a struct.

Actually the error text you quote describes the fix pretty well.

Something else: If you keep the set accessor of your property public you will have a mutable struct. Most people agree that mutable structs should be avoided and are "evil" because their copy-by-value semantics and the possibility of mutating an existing struct value (as in record.SampleCode = "Here's a new string for an old object";) don't go well together. Check the threads on mutable and immutable structs.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
1

You either need to call the default constructor or change the method name.

So;

      public struct LimitfailureRecord
      {
          public void init(string sampleCode)
          {
              SampleCode = sampleCode;
          }

          public string SampleCode { get; set; }
      }

Will work or just make the method definition; LimitfailureRecord(string sampleCode) : this()

The later is better because it only requires one call to make things work. If you go the init route you have do do new LimiFfailureRecord then call init after. structs in C# simply require you to call the default constructor, this isn't the case with classes which is why it will compile if you change it to a class.

evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
  • The `init` method is mutating the struct. This is not recommended. For example stuff like `someList[idx].init("asdf");` won't work the way one could think, with a mutable struct. – Jeppe Stig Nielsen Apr 12 '13 at 21:44