Question
In C#, what is the difference between a field and a property, and when should you use a field instead of a property?
Short Answer
By the end of this page, you will understand how fields and properties differ in C#, why properties are usually preferred for class design, and when using a field directly is still appropriate. You will also see practical examples, common mistakes, and how this choice appears in real codebases.
Concept
In C#, fields and properties both relate to storing or exposing data in a class, but they serve different purposes.
A field is a variable declared directly inside a class or struct. It stores the actual data.
class Person
{
public string name;
}
Here, name is a field.
A property is a member that provides controlled access to data. It looks like a variable from the outside, but it is actually made of get and/or set accessors.
class Person
{
public string Name { get; set; }
}
Here, Name is a property.
Why this matters
Properties are important because they support encapsulation. Encapsulation means a class controls how its internal state is accessed and changed.
With a property, you can:
- validate values before storing them
- make a value read-only or write-only
- compute a value instead of storing it directly
- change internal implementation later without changing external code
- trigger side effects such as logging or notifications
A field is simpler, but it exposes raw storage directly if it is public. That can make your code harder to maintain.
Common rule of thumb
- Use properties for data you want other code to access.
- Use fields mostly for private internal storage.
For example:
class Person
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Name cannot be empty.");
_name = value;
}
}
}
In this example:
_nameis a private field that stores the dataNameis a public property that controls access
This is a very common pattern in C#.
Auto-properties
C# also supports auto-properties, which let you write properties more concisely:
class Person
{
public string Name { get; set; }
}
This creates a hidden backing field automatically.
When to use a field instead of a property
Use a field when:
- the data is strictly internal to the class
- you do not need validation or access control beyond
private - you want a constant or readonly value
- you are storing the backing data for a property
Example:
class Counter
{
private int _count;
public void Increment()
{
_count++;
}
public int Count => _count;
}
Here _count is a private field because it is internal state. Count is a property because it exposes that state safely.
Public fields are usually discouraged
Public fields are possible:
class Person
{
public string Name;
}
But this is usually avoided because:
- you cannot easily add validation later without changing the API
- frameworks and tools often expect properties
- it breaks encapsulation
- you lose flexibility for future changes
That is why C# code usually exposes public properties, not public fields.
Mental Model
Think of a field as a box inside an object where data is stored.
Think of a property as a front desk for that box.
- The field is the actual storage room.
- The property is the receptionist that decides what goes in, what comes out, and under what rules.
If someone needs access to your object’s data, it is usually safer to send them through the front desk instead of letting them walk straight into the storage room.
That is why classes often keep fields private and expose properties publicly.
Syntax and Examples
Field syntax
class Product
{
private decimal _price;
}
This declares a private field named _price.
Property syntax
class Product
{
public decimal Price { get; set; }
}
This declares an auto-property. C# creates the hidden storage automatically.
Property with validation
class Product
{
private decimal _price;
public decimal Price
{
get { return _price; }
set
{
if (value < 0)
throw new ArgumentException("Price cannot be negative.");
_price = value;
}
}
}
This version uses a field to store the data and a property to control access.
Read-only property
class Product
{
public string Name { get; }
public Product(string name)
{
Name = name;
}
}
This allows reading Name from outside the class, but only the class itself can assign it during construction.
Computed property
class Rectangle
{
public int Width { get; set; }
public int Height { get; set; }
public int Area => Width * Height;
}
Area is a property, but it does not store data in its own field. It calculates the result when accessed.
Beginner-friendly example
class BankAccount
{
private decimal _balance;
public decimal Balance
{
get { return _balance; }
private set { _balance = value; }
}
public void Deposit(decimal amount)
{
if (amount <= 0)
throw new ArgumentException("Deposit amount must be positive.");
Balance += amount;
}
}
Explanation:
_balanceis the field that stores the moneyBalanceis the property that exposes the current balance- the setter is
private, so outside code cannot change the balance directly - the
Depositmethod controls valid updates
Step by Step Execution
Consider this example:
class User
{
private string _email;
public string Email
{
get { return _email; }
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Email is required.");
_email = value;
}
}
}
User user = new User();
user.Email = "alice@example.com";
Console.WriteLine(user.Email);
Step by step
- A
Userobject is created. - The object contains a private field named
_email. - The line
user.Email = "alice@example.com";does not write directly to_email. - Instead, it calls the property's
setaccessor. - The
setaccessor checks whether the value is null, empty, or whitespace. - Since
"alice@example.com"is valid, the code assigns it to_email. - The line
Console.WriteLine(user.Email);does not read_emaildirectly. - It calls the property's
getaccessor. - The
getaccessor returns_email. - The email is printed.
Key idea
A property can look like a normal variable when used, but behind the scenes it is method-like access with rules.
Real World Use Cases
Where fields are used
Fields are commonly used for:
- private backing storage inside classes
- constants and readonly values
- internal counters or cached values
- dependency references stored by a class
Example:
class EmailService
{
private readonly ILogger _logger;
public EmailService(ILogger logger)
{
_logger = logger;
}
}
_logger is a field because it is internal state used by the class.
Where properties are used
Properties are commonly used for:
- exposing model data in APIs
- configuration objects
- DTOs and view models
- settings and options classes
- public object state that other code needs to read or update
Example:
class AppSettings
{
public string ConnectionString { get; set; }
public int TimeoutSeconds { get; set; }
}
Many serializers and frameworks work naturally with properties.
In business logic
Properties help enforce rules:
class Employee
{
private decimal _salary;
public decimal Salary
{
get => _salary;
set
{
if (value < 0)
throw new ArgumentException("Salary cannot be negative.");
_salary = value;
}
}
}
This prevents invalid state from entering the object.
Real Codebase Usage
In real C# projects, developers usually follow this pattern:
- private fields for internal storage
- public properties for external access
Common patterns
Backing field + property
Used when validation or extra logic is needed.
private string _username;
public string Username
{
get => _username;
set
{
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentException("Username is required.");
_username = value;
}
}
Auto-property
Used when no custom logic is needed.
public string Title { get; set; }
Read-only property
Used to expose state safely.
public DateTime CreatedAt { get; } = DateTime.UtcNow;
Guard clauses in setters or methods
Validation often happens with guard clauses.
public int Age
{
get => _age;
set
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value));
_age = value;
}
}
Encapsulated updates
Sometimes properties have private setters, and methods control changes.
public decimal Balance { get; private set; }
public void Withdraw(decimal amount)
{
if (amount <= 0)
throw new ArgumentException("Amount must be positive.");
if (amount > Balance)
throw new InvalidOperationException("Insufficient funds.");
Balance -= amount;
}
This is common in domain models because it protects object state.
Why teams prefer properties
Using properties gives flexibility later. A simple auto-property can later be changed into a full property with validation without forcing callers to change how they use it.
Common Mistakes
1. Making fields public by default
Broken example:
class Person
{
public int Age;
}
Problem:
- any code can set
Ageto an invalid value - you cannot add validation without changing the API design
Better:
class Person
{
public int Age { get; set; }
}
Or better with validation:
class Person
{
private int _age;
public int Age
{
get => _age;
set
{
if (value < 0)
throw new ArgumentException("Age cannot be negative.");
_age = value;
}
}
}
2. Using a property when a private field is enough
Not every piece of internal state needs a property.
class Counter
{
private int _internalCount;
}
If no outside code needs direct access, a field is often simpler.
3. Recursively calling the property inside its own setter
Broken example:
class Person
{
public string Name
{
get { return Name; }
set { Name = value; }
}
}
Problem:
Namecalls itself forever- this causes a stack overflow
Correct version:
class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
4. Assuming properties are always just stored values
A property might calculate something:
public int Area => Width * Height;
So properties are not only for storage. They represent access to data, whether stored or computed.
5. Forgetting that fields and properties are different in reflection and frameworks
Many C# libraries, ORMs, serializers, and UI frameworks treat properties differently from fields. If a framework expects properties, exposing only fields may not work as expected.
Comparisons
| Concept | Field | Property |
|---|---|---|
| What it is | A variable inside a class or struct | A member with get and/or set accessors |
| Stores data directly | Yes | Sometimes; may use hidden or explicit backing field |
| Can contain logic | No | Yes |
| Supports validation | No | Yes |
| Can be computed | No | Yes |
| Best for public APIs | Usually no | Usually yes |
| Best for internal storage | Yes | Sometimes |
| Works well with encapsulation | Only if private | Yes |
Field vs auto-property
| Feature | Field | Auto-property |
|---|---|---|
| Syntax | private int _count; | public int Count { get; set; } |
| Direct storage | Yes | Yes, through compiler-generated backing field |
| Custom logic | No | Not unless expanded into full property |
| Typical use | Internal state | Exposed state |
When to choose which
- Choose a field for private internal data.
- Choose a property for anything that should be accessed from outside the class.
- Choose a property with a backing field when you need validation or custom behavior.
Cheat Sheet
Quick rules
- Field = actual variable inside a class
- Property = controlled access to data
- Prefer private fields and public properties
- Avoid public fields in most class designs
Syntax
Field:
private int _count;
Auto-property:
public int Count { get; set; }
Read-only property:
public int Count { get; }
Expression-bodied property:
public int Area => Width * Height;
Property with backing field:
private int _age;
public int Age
{
get => _age;
set
{
if (value < 0)
throw new ArgumentException("Age cannot be negative.");
_age = value;
}
}
Use fields for
- private storage
- backing fields
readonlydependencies- constants
Use properties for
- public data access
- validation
- read-only or restricted setters
- computed values
- framework-friendly models
Edge case reminder
This is wrong:
public string Name
{
get => Name;
set => Name = value;
}
Use a backing field instead.
FAQ
Should I use a field or property in C#?
Use a property for data that other classes need to access. Use a field mainly for private internal storage.
Are public fields bad in C#?
Not always, but they are usually discouraged in object-oriented design because they expose implementation details and reduce flexibility.
Do auto-properties use fields internally?
Yes. The compiler creates a hidden backing field for an auto-property.
Can a property exist without a field?
Yes. A property can compute its value instead of storing it, such as Area => Width * Height.
Why do frameworks prefer properties over fields?
Many serializers, UI frameworks, and libraries inspect properties for binding, validation, and configuration.
When is a field appropriate in C#?
A field is appropriate for private state, readonly dependencies, constants, and backing storage for properties.
Is a property just a method?
A property is not exactly a method, but it is implemented through accessor methods behind the scenes. It is used with field-like syntax for convenience.
Mini Project
Description
Build a small Student class that stores internal data safely and exposes it through properties. This demonstrates the real difference between fields and properties by combining private storage, validation, and controlled access.
Goal
Create a class that uses private fields for storage and public properties for safe access to student data.
Requirements
- Create a
Studentclass. - Store the student's name and age using private fields.
- Expose
NameandAgeas public properties. - Prevent empty names and negative ages.
- Print the student data from a
Mainmethod.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Access Modifiers and static: public, private, protected, and Defaults
Learn how C# public, private, protected, and default access control visibility, and how static differs from instance members.