Back to Blog
C#

C# Auto Property: Syntax and Usage Explained

c# auto property: Learn how C# auto-implemented properties work: syntax, initialization, access modifiers, and when to replace them with custom properties.

C# propertiesauto-implemented propertiesproperty initializationC# syntaxbacking fields
Diagram showing a C# auto property declaration with compiler-generated backing field

C# Auto Property: Syntax, Initialization, and When to Use Them

Auto-implemented properties in C# let you declare a property without writing a backing field manually. The compiler generates a private, anonymous backing field that stores the property value. This reduces boilerplate and makes property declarations concise.

public class Customer { public string Name { get; set; } public int Age { get; set; } }

Each { get; set; } pair tells the compiler to create a hidden backing field and wire it to the getter and setter. The property behaves like a normal property, but you never see the backing field in your code.

How Auto Properties Work Under the Hood

The compiler transforms an auto property into a property with a backing field. For public string Name { get; set; }, the generated code is roughly:

private string _name; public string Name { get { return _name; } set { _name = value; } }

The backing field name is compiler-generated and not accessible from your code. This transformation happens at compile time, so there is no runtime overhead compared to a manually written property.

Initializing Auto Properties

Before C# 6, you had to assign a default value in a constructor or rely on the default value of the type. C# 6 introduced auto-property initializers, allowing you to set an initial value directly:

public class Product { public string Sku { get; set; } = "UNASSIGNED"; public decimal Price { get; set; } = 0.0m; }

The initializer runs when the object is constructed, before the constructor body. This is useful for providing sensible defaults without extra code.

Read-Only and Write-Only Auto Properties

You can omit the setter to create a read-only auto property. The backing field can still be assigned from within the constructor or via an initializer:

public class Order { public DateTime CreatedAt { get; } = DateTime.UtcNow; }

In C# 6 and later, a getter-only auto property can be assigned in the constructor. This is a common pattern for immutable objects:

public class User { public string Id { get; } public User(string id) { Id = id; } }

Write-only auto properties (setter only) are possible but rarely useful; they are allowed syntactically but usually indicate a design issue.

Access Modifiers on Auto Properties

You can apply different access modifiers to the getter and setter. For example, a public getter and a private setter:

public class Account { public decimal Balance { get; private set; } public void Deposit(decimal amount) { Balance += amount; } }

This pattern is common for properties that should be readable externally but only modified inside the class. The compiler still generates a backing field, but the setter's accessibility is restricted.

When Auto Properties Are Not Enough

Auto properties work well when there is no additional logic in the getter or setter. Once validation, change notification, or lazy loading is needed, you must switch to a manually implemented property.

private string _email; public string Email { get { return _email; } set { if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Email cannot be empty."); _email = value; } }

Auto properties also cannot be used with fields that require custom serialization logic or when the backing field must be accessed directly for performance reasons. In those cases, a manual property gives you full control.

Performance and Memory Considerations

Auto properties do not add measurable overhead. The compiler generates the same IL as a manually written property with a backing field. The only difference is source code brevity. There is no reflection cost at runtime, and the backing field is a normal private field.

One subtle point: because the backing field is hidden, you cannot apply attributes to it directly. If you need to attribute the field (for example, [NonSerialized]), you must write the property manually. This is a maintainability tradeoff, not a performance one.

Compatibility and Language Versions

Auto properties have existed since C# 3.0. Auto-property initializers and getter-only auto properties require C# 6 or later. If you are targeting an older compiler, you need to initialize properties in the constructor. Modern .NET projects use C# 9 or later, so these features are available, but if you maintain legacy code, be aware of the version requirement.

Choosing Between Auto and Manual Properties

Use an auto property when:

  • The getter and setter simply read and write a field.
  • No validation, transformation, or side effects are needed.
  • You want to keep the code concise.

Use a manual property when:

  • You need to add validation or change notification.
  • The property requires computed logic.
  • You need to control the backing field directly, for example, to apply attributes.

The decision is about code clarity and maintainability. Auto properties reduce boilerplate, but they hide the implementation. If the property logic grows, refactor to a manual property.

c# auto property: Practical Usage and Code Examples | RYUSLOG DEV