Similar to the JVM, the CLR can offer binary compatibility of libraries, which is something Microsoft cares a great deal about. Changing a public readonly field in to a public readonly property is source-compatible, but not binary-compatible. That's why properties are generally preferred, even when you don't strictly need one. The language was actively discouraging either immutability or binary-compatibility by making it more verbose to get a trivial readonly property.
A getter-only property can only be set on initialization of the class, so either with a fixed value or one from a constructor. That does make it the equivalent of a read-only field, but it's a lot easier to keep byte-level parity with future versions.
In its simplest form, it means you can do this:
public property Foo { get; } = 5;
Your class now has a Foo property that nobody can set, not even methods in the class itself, but that can be publicly read.
These become a lot more useful with primary constructors (also a new C# 6 feature):
public class MyImmutableClass(int usersFoo) {
public property Foo { get; } = usersFoo;
}
This will create a constructor on the class that takes the usersFoo argument, and immediately assign the value of that argument to your read-only automatic property. It makes immutable classes a lot easier to create, and guarantees that they'll stay immutable.
edit: Permit made it clear that primary contructors have been dropped from the C# 6 spec. You'll just have to assign your readonly properties from regular constructors then :)
Internally, .Net automatic properties are compiled with a backing field and a getter and setter method. In the case of a read-only auto property, they will omit the setter, so there is no public artifact that could be abused.
Aha I must have missed that news. I'll update my comment. Can't say I'm sad to see them go, they were useful but turn a complicated class into a clusterfuck.
Because a property is actually a method, so other, internal state could change what the property returns. Think of something like an "IsConnectionOpen" flag. The class' internals may change it as if it is not readonly, but to the consuming code, the IsConnectionOpen property should appear readonly.
Do you know where it is in the video? Are they not talking about something like this?
public bool IsOpen{get; private set;}
public void Open(){
try{
// do some complex work
this.IsOpen = true;
}
catch{
this.IsOpen = false;
}
}
public void Close(){
// do some other work
this.IsOpen = false;
}
I see. Maybe they mean "implicit private set"? Otherwise, one of the sibling comments has a good point about the binary compatibility issues with fields vs properties.
It's not equivalent. The getter-only auto-property will not have any setter at all. Previously, it had to have at least a private setter, which means that you couldn't strictly guarantee that it wasn't being updated. I used to write read-only properties the long way just to guarantee that they were actually read-only.
edit: is it "same as a public readonly field, but it's a property"?