C# Auto Property: Syntax and Usage Explained
Learn how C# auto-implemented properties work: syntax, initialization, access modifiers, and when to use a manual property instead.
C# Auto Property Basics
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.
Getter-Only Auto Properties
You can omit the setter to create a getter-only auto property. The backing field can be assigned from an initializer or from within the constructor:
public class Order { public DateTime CreatedAt { get; } = DateTime.UtcNow; }
In C# 6 and later, a getter-only auto property can also 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; } }
Setter-only properties are rarely useful, and C# does not support a setter-only auto property. If you need a write-only property, implement it manually to keep the intent clear.
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 when the backing field must be accessed directly inside the class or needs an attribute. In those cases, a manual property gives you full control.
Performance and Memory Considerations
Auto properties do not introduce special runtime overhead. The compiler generates the same IL as a manually written property with a simple backing field. The only difference is source code brevity. There is no reflection lookup at runtime; 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. Most current .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.