Automatically implemented properties
Automatically implemented properties make property-declaration more concise when no other logic is required in the property accessors. They also enable client code to create objects. When you declare a property as shown in the following example, the compiler creates a private, anonymous backing field that can only be accessed through the property's get
and set
accessors. init
accessors can also be declared as automatically implemented properties.
The following example shows a simple class that has some automatically implemented properties:
// This class is mutable. Its data can be modified from
// outside the class.
public class Customer
{
// Auto-implemented properties for trivial get and set
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerId { get; set; }
// Constructor
public Customer(double purchases, string name, int id)
{
TotalPurchases = purchases;
Name = name;
CustomerId = id;
}
// Methods
public string GetContactInfo() { return "ContactInfo"; }
public string GetTransactionHistory() { return "History"; }
// .. Additional methods, events, etc.
}
class Program
{
static void Main()
{
// Initialize a new object.
Customer cust1 = new Customer(4987.63, "Northwind", 90108);
// Modify a property.
cust1.TotalPurchases += 499.99;
}
}
You can't declare automatically implemented properties in interfaces. Automatically implemented and field backed properties declare a private instance backing field, and interfaces can't declare instance fields. Declaring a property in an interface without defining a body declares a property with accessors. Each type that implements that interface must implement that property.
You can initialize automatically implemented properties similarly to fields:
public string FirstName { get; set; } = "Jane";
The class that is shown in the previous example is mutable. Client code can change the values in objects after creation. In complex classes that contain significant behavior (methods) and data, it's often necessary to have public properties. However, for small classes or structs that just encapsulate a set of values (data) and have little or no behaviors, you should use one of the following options for making the objects immutable:
- Declare only a
get
accessor (immutable everywhere except the constructor). - Declare a
get
accessor and aninit
accessor (immutable everywhere except during object construction). - Declare the
set
accessor as private (immutable to consumers).
For more information, see How to implement a lightweight class with automatically implemented properties.
You might need to add validation to an automatically implemented property. C# 13 adds field backed properties as a preview feature. You use the field
keyword to access the compiler synthesized backing field of an automatically implemented property. For example, you could ensure that the FirstName
property in the preceding example can't be set to null
or the empty string:
public string FirstName
{
get;
set
{
field = (string.IsNullOrWhiteSpace(value) is false
? value
: throw new ArgumentException(nameof(value), "First name can't be whitespace or null"));
}
} = "Jane";
This feature enables you to add logic to accessors without requiring you to explicitly declare the backing field. You use the field
keyword to access the backing field generated by the compiler.
Important
The field
keyword is a preview feature in C# 13. You must be using .NET 9 and set your <LangVersion>
element to preview
in your project file in order to use the field
contextual keyword.
You should be careful using the field
keyword feature in a class that has a field named field
. The new field
keyword shadows a field named field
in the scope of a property accessor. You can either change the name of the field
variable, or use the @
token to reference the field
identifier as @field
. You can learn more by reading the feature specification for the field
keyword.