2

Observe the following...

//pattern 1
public class Cheesesteak
{
    public string bread {get; private set}
    public string cheese {get; private set}

    public Cheesesteak()
    {
        bread = "Amoroso"; 
        cheese = "Cheez Whiz";
    }
}

//pattern 2
public class Cheesesteak
{
    public string bread 
    {
        get {return bread;}
        set 
        {
            bread = "Amoroso";
        }
    }
    public string cheese 
    {
        get {return cheese;}
        set
        {
            cheese = "Cheez Whiz";
        }
    }
    public Cheesesteak() {}
}

This is a curiosity question. Is there any advantage or particular reason that you would set the variables in the definition of the "set" versus declaring them in the constructor? My initial guess is pattern 1 is shorter, but less efficient during compile.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
tyh
  • 977
  • 1
  • 8
  • 22

3 Answers3

8

Is there any advantage or particular reason that you would set the variables in the definition of the "set" versus declaring them in the constructor?

No, and in fact, this is probably not what you want at all. This will make it impossible to set "break" or "cheese", as any call, such as bread = "rye";, would set it to "Amoroso" (if it worked, but will cause a StackOverflowException). Also note that trying to retrieve the value in your code will cause a StackOverflowException, and the property getter returns the property and not a backing field value.

You were likely thinking of this:

public class Cheesesteak
{
    private string bread = "Amoroso";
    public string Bread 
    {
        get {return bread;}
        set 
        {
            bread = value;
        }
    }

    // ...

The only advantage here is you're setting the "default" value where the field is defined, which can help with maintainability or readability in some cases, and even potentially eliminate the need for a defined constructor, which might reduce the overall length of code.

My initial guess is pattern 1 is shorter, but less efficient during compile.

In general, setting the fields inline vs. setting them in a constructor does not make this less efficient. The compiler will cause the type's actual constructor to set the fields first then run the constructor code, so both versions end up (for practical purposes) the same in terms of the compiled IL. This isn't a matter of efficiency, but rather of code readability and maintainability.

Note that, if you wanted the property to always be a constant (ie: Bread should always return "Amoroso"), you can just make the property have a getter and no setter:

public string Bread { get { return "Amoroso"; } }

I suspect this is not the case, but I thought I'd mention it as an option just in case it's what you intended.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
1

Well the second option will result in a StackOverflowException whenever a user tries to assign or access the properties, versus the first which will only allow private access to them.

You maybe meant something like:

private string bread = "Amaroso";
public string Bread
{
    get { return bread; }
    private set
    {
        bread = value;
    }
}

Which will initialize the property with "Amaroso" but will not allow it to be set publicly.

NominSim
  • 8,447
  • 3
  • 28
  • 38
  • And also when the user tries to retrieve the property value. Both accessors are SOE traps waiting to explode. – cdhowie Jan 09 '13 at 21:32
0

No, they are completely different. The get and set blocks are actually methods that get executed when the property is read from or written to. Nether of them have anything to do with initialization.

var x = thing.Property; // Property's "get" accessor method is executed
thing.Property = x; // Property's "set" accessor method is executed

In your second example, both property accessors will infinitely recurse on themselves and you will get a StackOverflowException.

cdhowie
  • 158,093
  • 24
  • 286
  • 300