[ACCEPTED]-C# Automatic Properties - Why Do I Have To Write "get; set;"?-automatic-properties
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; }
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.
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
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; }
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.
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?
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.
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; } }
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
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.