Sie sind syntaktischer Zucker für zwei verschiedene Dinge. Ersteres initialisiert ein Backing-Feld und setzt es zum Ausdruck auf der rechten Seite der Zuweisung während der Feldinitialisierung. Letzteres erstellt ein get
, das genau das tut, was im Ausdruck steht.
public override bool CanRead { get; } = true;
ist äquivalent zu
private readonly bool __backingFieldCanRead = true;
public override bool CanRead
{
get
{
return __backingFieldCanRead;
}
}
Dies
public override bool CanRead => true;
ist äquivalent zu
public override bool CanRead
{
get
{
return true;
}
}
Sie verhalten sich unterschiedlich. Im ersten Fall wird der Wert der Eigenschaft beim Erstellen des Objekts und der Feldinitialisierung gesetzt, im anderen Fall wird der Ausdruck jedes Mal ausgewertet, wenn der Getter der Eigenschaft aufgerufen wird. Im einfachen Fall eines bools ist das Verhalten gleich. Wenn der Ausdruck jedoch Nebenwirkungen verursacht, sind die Dinge anders. Betrachten Sie dieses Beispiel:
class Program
{
static void Main(string[] args)
{
var fooBar1 = new FooBar();
Console.WriteLine(fooBar1.Baz);
Console.WriteLine(fooBar1.Baz);
var fooBar2 = new FooBar();
Console.WriteLine(fooBar2.Baz);
Console.WriteLine(fooBar2.Baz);
}
}
public class FooBar
{
private static int counter;
public int Baz => counter++;
}
Hier werden "0, 1, 2, 3" gedruckt. Das statische counter
-Feld wird jedes Mal inkrementiert, wenn der Getter der Eigenschaft aufgerufen wird. Jedoch mit einem Eigenschafts-Initializer:
public int Baz { get; } = counter++;
werden dann "0, 0, 1, 1" gedruckt, weil der Ausdruck im Konstruktor des Objekts ausgewertet wird.