[ACCEPTED]-C# Automatic Properties - Why Do I Have To Write "get; set;"?-automatic-properties

Accepted answer
Score: 67

Because you might want a read-only property:

public int Foo { get; private set; }

Or 1 Write-only property:

public int Foo { private get; set; }
Score: 57

ERROR: A property or indexer may not be passed as an out or ref parameter

If you didn't specify {get; set;} then the compiler 14 wouldn't know if it's a field or a property. This 13 is important becasue while they "look" identical 12 the compiler treats them differently. e.g. Calling 11 "InitAnInt" on the property raises an error.

class Test
{
    public int n;
    public int i { get; set; }
    public void InitAnInt(out int p)
    {
        p = 100;
    }
    public Test()
    {
        InitAnInt(out n); // This is OK
        InitAnInt(out i); // ERROR: A property or indexer may not be passed 
                          // as an out or ref parameter
    }
}

You 10 shouldn't create public fields/Variables 9 on classes, you never know when you'll want 8 to change it to have get & set accessors, and 7 then you don't know what code you're going 6 to break, especially if you have clients 5 that program against your API.

Also you can 4 have different access modifiers for the 3 get & set, e.g. {get; private set;} makes the 2 get public and the the set private to the 1 declaring class.

Score: 19

Just thought I would share my findings on 23 this topic.

Coding a property like the following, is 22 a .net 3.0 shortcut call “auto-implemented property”.

public int MyProperty { get; set; }

This saves 21 you some typing. The long way to declare 20 a property is like this:

private int myProperty;
public int MyProperty 
{
  get { return myProperty; }
  set { myProperty = value; } 
}

When you use the 19 “auto-implemented property” the compiler 18 generates the code to wire up the get and 17 set to some “k_BackingField”. Below is the 16 disassembled code using Reflector.

public int MyProperty
{
    [CompilerGenerated]
    get
    {
        return this.<MyProperty>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        this.<MyProperty>k__BackingField = value;
    }
}

disassembled C# code from IL

Also 15 wires up a method for the setter and getter.

[CompilerGenerated]
public void set_MyProperty(int value)
{
    this.<MyProperty>k__BackingField = value;
}
[CompilerGenerated]
public int get_MyProperty()
{
    return this.<MyProperty>k__BackingField;
}

disassembled C# code from IL

When 14 you declare a read only auto-implemented 13 property, by setting the setter to private:

 public int MyProperty { get; private set; }

All 12 the compiler does flag the "set" as private. The 11 setter and getter method say the same.

public int MyProperty
{
    [CompilerGenerated]
    get
    {
        return this.<MyProperty>k__BackingField;
    }
    private [CompilerGenerated]
    set
    {
        this.<MyProperty>k__BackingField = value;
    }
}

disassembled C# code from IL

So 10 I am not sure why the framework require 9 both the get; and set; on an auto-implemented 8 property. They could have just not written 7 the set and setter method if it was not 6 supplied. But there may be some compiler 5 level issue that makes this difficult, I 4 don't know.

If you look at the long way of 3 declaring a read only property:

public int myProperty = 0;
public int MyProperty
{
    get { return myProperty; }
}  

And then 2 look at the disassembled code. The setter 1 is not there at all.

public int Test2
{
    get
    {
        return this._test;
    }
}

public int get_Test2()
{
    return this._test;
}

disassembled C# code from IL

Score: 17

Because you need some way to distinguish 2 it from plain fields.

It's also useful to 1 have different access modifiers, e.g.

public int MyProperty { get; private set; }
Score: 5

The compiler needs to know if you want it 2 to generate a getter and/or a setter, or 1 perhaps are declaring a field.

Score: 2

If the property didn't have accessors, how 2 would the compiler separate it from a field? And 1 what would separate it from a field?

Score: 2

Well, obviously you need a way of disambiguating 8 between fields and properties. But are 7 required keywords really necessary? For 6 instance, it's clear that these two declarations 5 are different:

public int Foo;
public int Bar { }

That could work. That is, it's 4 a syntax that a compiler could conceivably 3 make sense of.

But then you get to a situation 2 where an empty block has semantic meaning. That 1 seems precarious.

Score: 2

Since no one mentioned it... you could make 3 the auto-property virtual and override it:

public virtual int Property { get; set; }

If 2 there was no get/set, how would it be overridden? Note 1 that you are allowed to override the getter and not the setter:

public override int Property { get { return int.MinValue; } }
Score: 2

Also, because ever since C# 6.0 (in Visual 8 Studio 2015, at the time of this answer 7 available in version Ultimate Preview) you 6 may implement a true read-only property:

public string Name { get; }
public string Name { get; } = "This won't change even internally";

... as 5 opposed to currently imperfect workaround 4 with public getter/private setter pair:

public string Name { get; private set; }

public Constructor() { Name="As initialised"; }
public void Method() { Name="This might be changed internally. By mistake. Or not."; }

Example 3 of the above below (compiled and executable 2 online here).

using System;

public class Propertier {
    public string ReadOnlyPlease { get; private set; }

    public Propertier()  { ReadOnlyPlease="As initialised"; }
    public void Method() { ReadOnlyPlease="This might be changed internally"; }
    public override string ToString() { return String.Format("[{0}]",ReadOnlyPlease); }
}

public class Program {
    static void Main() {
        Propertier p=new Propertier();
        Console.WriteLine(p);

//      p.ReadOnlyPlease="Changing externally!";
//      Console.WriteLine(p);

        // error CS0272: The property or indexer `Propertier.ReadOnlyPlease' cannot be used in this context because the set accessor is inaccessible
        // That's good and intended.

        // But...
        p.Method();
        Console.WriteLine(p);
    }
}

Other tasty news about C# 6.0 available 1 as official preview video here.

More Related questions