C# Properties, Fields, and Methods Explained with Examples

A clear, practical guide to C# fields, properties, and methods in 2026: what each one is for, when to use which, and how to design clean classes you will not hate in six months.

C#beginner
13 min read

Open any real C# class and you will see three kinds of members: fields (plain variables that hold the data), properties (a controlled way to read and write that data), and methods (the things the class actually does). Get the relationship between the three right and your code will read clearly six months from now. Get it wrong and even small classes turn into a mess.

This guide explains exactly what each one is, when to choose which, and how the modern 2026 patterns — including the new field keyword in C# 14 — change the day-to-day defaults. If C# itself is brand new, start with What is C#? A Beginner's Guide to .NET Development in 2026 first.

Fields: Where the Data Actually Lives

A field is a variable declared inside a class. It holds the state of one particular object.

csharpcsharp
public class Order
{
    private string _id;
    private decimal _total;
}

Fields are usually private — only the class itself touches them. Adding readonly means the value can only be set in the constructor, which is the right default for anything that should never change after the object is built. The leading underscore is a common convention to mark "this is a backing field, not a property."

Public fields exist but are almost always a mistake. They give the outside world direct access to your internal storage, so the moment you decide to add validation or computed logic, every caller breaks. Use a property instead.

Properties: Controlled Access to Data

A property is a field with a gatekeeper. From the outside it looks like a variable; on the inside it is two methods (get and set) the compiler generates for you.

csharpcsharp
public class Order
{
    public string Id { get; }            // read-only auto-property
    public decimal Total { get; private set; } // public read, private write
    public int Quantity { get; set; }    // full read/write
 
    public Order(string id) { Id = id; }
}

Three patterns to recognise:

  • { get; } — read-only after construction. Set once in the constructor.
  • { get; private set; } — public can read; only the class itself can change it.
  • { get; set; } — full read/write. Use sparingly; usually means you should rethink the design.

Auto-properties are the default. The compiler quietly creates a hidden backing field for you. The day you need real logic — validation, lazy initialisation, raising an event when the value changes — you switch to a property with an explicit body without changing a single caller. That is exactly why properties exist.

The New field Keyword (C# 13/14)

For years, the moment you needed any logic in a setter you had to declare your own backing field, name it, and remember the underscore. C# 13 added a field contextual keyword that gives you the auto-generated backing field by name.

csharpcsharp
public string Email
{
    get;
    set => field = value?.Trim().ToLowerInvariant() ?? throw new ArgumentNullException();
}

You skip the explicit private string _email; declaration and let the compiler manage the storage. Reach for it any time you want a tiny custom setter without all the boilerplate. Available in C# 13 and refined in C# 14 — the version shipping with .NET 10 LTS.

Methods: The Behaviour

A method is a function attached to a class. It reads or modifies the object's state and returns a value (or void if it does not).

csharpcsharp
public class Order
{
    public string Id { get; }
    public List<Item> Items { get; } = new();
    public decimal Subtotal => Items.Sum(i => i.Price * i.Quantity);
 
    public Order(string id) { Id = id; }
 
    public void Add(Item item) => Items.Add(item);
    public bool TryGet(string sku, out Item? item) => (item = Items.FirstOrDefault(i => i.Sku == sku)) is not null;
}
 
public record Item(string Sku, string Name, decimal Price, int Quantity);

Notice the => (expression-bodied) syntax. When a method or property body is a single expression, drop the braces and the return. It reads better and the compiler generates the same IL.

Subtotal here is interesting: it is a property whose get runs every time you ask for it. If something is cheap to compute and changes when other state changes, prefer a computed property over a stored field — you cannot get them out of sync.

When to Use Which

The 2026 rule of thumb almost everyone converges on:

You want...Use
Simple read-only datapublic T X { get; } (set in ctor)
Read/write data with no logicpublic T X { get; set; }
Data with validation or normalisationproperty with field keyword
Internal storage no one else should seeprivate (or private readonly) field
A value derived from other statecomputed property => ...
Behaviour (does something, returns a result)method
Pure data transfer objectrecord (which is mostly properties)

If a class has any "do something" verbs — Submit, Calculate, Add, Reload — those are methods. Everything else is a property or a field.

A Real Example

Putting it together:

csharpcsharp
public class Customer
{
    public Guid Id { get; }
    public string Name { get; private set; }
    public string Email
    {
        get;
        set => field = value?.Trim().ToLowerInvariant() ?? throw new ArgumentNullException();
    }
    private readonly List<Order> _orders = new();
    public IReadOnlyList<Order> Orders => _orders;
 
    public Customer(string name, string email) { Id = Guid.NewGuid(); Name = name; Email = email; }
    public void Rename(string name) => Name = name;
    public Order PlaceOrder() { var o = new Order(Guid.NewGuid().ToString()); _orders.Add(o); return o; }
}

Id is read-only. Name is publicly readable but only Rename can change it (control point for logging or validation later). Email normalises on write. Orders exposes a read-only view of an internally mutable list. PlaceOrder is the only way to add an order. The class is impossible to put into an invalid state from outside.

Common Mistakes Beginners Make

  • Making fields public. Use auto-properties instead.
  • Writing custom get/set for every property when an auto-property would do.
  • Exposing a List<T> directly. Expose IReadOnlyList<T> and let methods mutate the underlying list.
  • Confusing methods and properties. If it has side effects or runs noticeably long, it should be a method (so callers know it costs something).
  • Using Newtonsoft.Json attributes on properties. The built-in System.Text.Json is the modern default.

Quick Reference

  • Field: private readonly T _x; — internal storage
  • Auto-property: public T X { get; set; } — exposed storage with a hidden backing field
  • Read-only auto-property: public T X { get; } — set in ctor only
  • Computed property: public T X => expr; — derived value, no storage
  • Method (expression-bodied): public T Do() => expr;
  • New field keyword (C# 13/14): set => field = value?.Trim();
  • Records for value classes: public record Money(decimal Amount, string Currency);
  • Use IReadOnlyList<T> / IReadOnlyDictionary<TK,TV> to expose collections without giving up control
Rune AI

Rune AI

Key Insights

  • Default fields to private readonly; expose data through properties, not public fields.
  • Use auto-properties ({ get; set; }, { get; private set; }, { get; }) until you genuinely need logic.
  • The new field keyword in C# 13/14 lets you write small custom setters without an explicit backing field.
  • Use computed properties for derived values; methods for actions and side effects.
  • Expose collections as IReadOnlyList<T> or IReadOnlyDictionary<TK,TV> and mutate them through methods.
RunePowered by Rune AI

Frequently Asked Questions

What is the difference between a field and a property?

field is the actual storage. A property is methods (`get`/`set`) wrapped around storage. Fields are an implementation detail; properties are the public contract.

Should every property have a setter?

No. Default to `{ get; }` (read-only). Add `set` only when callers truly need to change the value. Many bugs come from properties being more mutable than they need to be.

When should I use a method vs a property?

Properties should feel free — like reading a variable. If the work has side effects, throws under normal use, or runs noticeably long, make it a method so the caller knows.

What is the new `field` keyword?

C# 13/14 contextual keyword that lets you reference the auto-generated backing field of an auto-property without having to declare your own. Useful when you need a small custom setter without the boilerplate.

Should I prefer records over classes?

Use a `record` for immutable value-style data (DTOs, query results, configuration). Use a `class` for behaviour-heavy or mutable types. Records give you `Equals`, `GetHashCode`, and `with` expressions for free.

Conclusion

Fields hold the data. Properties expose it safely. Methods are the actions. Get those three roles clear in your head and a C# class becomes easy to design and easy to read. Build the Customer example above, then turn it into a small console app — the patterns scale from a five-line script to a production microservice without changing.