Question

Field vs Property in C#: What’s the Difference and When to Use Each

csharpooppropertiesfield

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:

  • _name is a private field that stores the data
  • Name is 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.

Take Quiz

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:

  • _balance is the field that stores the money
  • Balance is the property that exposes the current balance
  • the setter is private, so outside code cannot change the balance directly
  • the Deposit method 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

  1. A User object is created.
  2. The object contains a private field named _email.
  3. The line user.Email = "alice@example.com"; does not write directly to _email.
  4. Instead, it calls the property's set accessor.
  5. The set accessor checks whether the value is null, empty, or whitespace.
  6. Since "alice@example.com" is valid, the code assigns it to _email.
  7. The line Console.WriteLine(user.Email); does not read _email directly.
  8. It calls the property's get accessor.
  9. The get accessor returns _email.
  10. 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.

Take Quiz

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 Age to 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:

  • Name calls 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

ConceptFieldProperty
What it isA variable inside a class or structA member with get and/or set accessors
Stores data directlyYesSometimes; may use hidden or explicit backing field
Can contain logicNoYes
Supports validationNoYes
Can be computedNoYes
Best for public APIsUsually noUsually yes
Best for internal storageYesSometimes
Works well with encapsulationOnly if privateYes

Field vs auto-property

FeatureFieldAuto-property
Syntaxprivate int _count;public int Count { get; set; }
Direct storageYesYes, through compiler-generated backing field
Custom logicNoNot unless expanded into full property
Typical useInternal stateExposed 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.
Take Quiz

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
  • readonly dependencies
  • 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.

Take Quiz

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

  1. Create a Student class.
  2. Store the student's name and age using private fields.
  3. Expose Name and Age as public properties.
  4. Prevent empty names and negative ages.
  5. Print the student data from a Main method.
Take Quiz

Keep learning

Related questions

View more