Επεξεργασία

Κοινή χρήση μέσω


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 an init 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.

See also