views:

51

answers:

5

I have the following bit of code:

public struct Interval
{
    public double Min { get; set; }
    public double Max { get; set; }

    public Interval(double min = double.MinValue, double max = double.MaxValue)
    {
        Min = min;
        Max = max;
    }
}

The compiler is complaining that

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

Which is something that I don't understand, since my constructor is fully initializing the values of this struct. Isn't it?

+1  A: 

Heed the error message and add a call to the default constructor like so:

public Interval(
    double min = double.MinValue,
    double max = double.MaxValue
)
    : this() {
        Min = min;
        Max = max;
}

The issue is that as written the backing fields aren't initialized; that makes the compiler very unhappy. However, the default parameterless constructor will initialize these fields for you which is why the problem disappears when we chain a call to that constructor.

Jason
Wow, that's confusing indentation. It makes it look like the body is associated with `this()` (it isn't).
Ben Voigt
Oh Lord, downvoting correct answers because of non-standard indentation? How silly.
Hans Passant
@Ben Voigt: Really? Anyone familiar with C# constructor chaining syntax would, I think, correctly read this. Does putting the brace on the next line really change anything?
Jason
@Hans: Who downvoted? I certainly didn't.
Ben Voigt
+5  A: 

Your constructor is trying to set properties - which it can't do until it knows that all the fields have been initialized. (You can't call any instance methods or access any properties until all the struct's fields are definitely assigned.) It's a quirk which manifests itself when you're using automatically implemented properties: you have fields that you can't access other than via the property, but you can't use the property before assigning the field a value! The fix is simple - just add a call to the parameterless constructor:

public Interval(double min = double.MinValue, double max = double.MaxValue)
    : this()
{
    Min = min;
    Max = max;
}

This works because the parameterless constructor assigns the default values to all fields, after which you can use the properties without any problems.

However, I'd recommend against using mutable structs in the first place.

Jon Skeet
Now that I think of it, the reason for them to be structs was that I was actually have them immutable.
devoured elysium
@devoured elysium: You can make them immutable as classes too, of course :)
Jon Skeet
A: 

It compiles just fine for me: http://ideone.com/mgBpt

What version of C# and compiler are you using?

Ben Voigt
@Ben: That fails for me with both Mono and the MS compiler - and it *should* fail.
Jon Skeet
A: 

Add :this() to the ctor:

public Interval(...args...) : this() {
    ... Code ...
}
Marc Gravell
A: 

I just wrote this few days back.

http://www.abhisheksur.com/2010/10/hidden-facts-on-c-constructor-in.html

If you write a constructor for your structure, you need to initialize each and every member of your struct before returning from the constructor. Backing fields might be creating some issue with your code, you can fix it using the call to Default constructor.

this()

abhishek