12 minlesson

Fields and Properties

Fields and Properties

Fields and properties are how classes store data. This lesson explains the difference between them and when to use each.

Fields

Fields are variables declared directly in a class:

csharp
1class Person
2{
3 public string name; // Field
4 public int age; // Field
5 private decimal salary; // Private field
6}

Field Naming Convention

csharp
1class Example
2{
3 public int PublicField; // PascalCase (public)
4 private int _privateField; // _camelCase (private)
5 private int privateField; // camelCase (also acceptable)
6}

Problems with Public Fields

Public fields expose internal data directly:

csharp
1class Person
2{
3 public int Age;
4}
5
6Person p = new Person();
7p.Age = -5; // Invalid age, but allowed!
8p.Age = 500; // Also allowed!

There's no validation or control over what values can be set.

Properties

Properties provide controlled access to data with getters and setters:

csharp
1class Person
2{
3 private int _age; // Private backing field
4
5 public int Age
6 {
7 get { return _age; }
8 set
9 {
10 if (value >= 0 && value <= 150)
11 {
12 _age = value;
13 }
14 }
15 }
16}
17
18Person p = new Person();
19p.Age = 25; // Calls the setter
20int a = p.Age; // Calls the getter

Property Syntax

Full Property (with backing field)

csharp
1class Person
2{
3 private string _name;
4
5 public string Name
6 {
7 get { return _name; }
8 set { _name = value; }
9 }
10}

Auto-Implemented Property

When you don't need validation, use auto-properties:

csharp
1class Person
2{
3 public string Name { get; set; } // Compiler creates backing field
4 public int Age { get; set; }
5}

Expression-Bodied Properties

csharp
1class Person
2{
3 private string _name;
4
5 public string Name
6 {
7 get => _name;
8 set => _name = value;
9 }
10}

Read-Only Properties

Get-Only Auto-Property

csharp
1class Circle
2{
3 public double Radius { get; } // Can only be set in constructor
4
5 public Circle(double radius)
6 {
7 Radius = radius;
8 }
9}

Calculated Property (no setter)

csharp
1class Circle
2{
3 public double Radius { get; set; }
4
5 public double Area
6 {
7 get { return Math.PI * Radius * Radius; }
8 }
9
10 // Or using expression body
11 public double Circumference => 2 * Math.PI * Radius;
12}

Property Initializers

Set default values:

csharp
1class Person
2{
3 public string Name { get; set; } = "Unknown";
4 public int Age { get; set; } = 0;
5 public bool IsActive { get; set; } = true;
6}
7
8Person p = new Person();
9Console.WriteLine(p.Name); // "Unknown"

Private Setters

Allow reading from outside, but only setting from within the class:

csharp
1class BankAccount
2{
3 public string AccountNumber { get; private set; }
4 public decimal Balance { get; private set; }
5
6 public BankAccount(string number)
7 {
8 AccountNumber = number;
9 Balance = 0;
10 }
11
12 public void Deposit(decimal amount)
13 {
14 if (amount > 0)
15 {
16 Balance += amount; // Can set from inside
17 }
18 }
19}
20
21// Usage
22BankAccount account = new BankAccount("12345");
23Console.WriteLine(account.Balance); // Can read
24// account.Balance = 1000; // Error! Cannot set from outside
25account.Deposit(100); // This works

Validation in Setters

csharp
1class Product
2{
3 private string _name;
4 private decimal _price;
5
6 public string Name
7 {
8 get => _name;
9 set
10 {
11 if (string.IsNullOrWhiteSpace(value))
12 throw new ArgumentException("Name cannot be empty");
13 _name = value.Trim();
14 }
15 }
16
17 public decimal Price
18 {
19 get => _price;
20 set
21 {
22 if (value < 0)
23 throw new ArgumentException("Price cannot be negative");
24 _price = value;
25 }
26 }
27}

Init-Only Properties (C# 9+)

Can only be set during initialization:

csharp
1class Person
2{
3 public string Name { get; init; }
4 public int Age { get; init; }
5}
6
7// Can set during initialization
8Person p = new Person { Name = "Alice", Age = 25 };
9
10// Cannot modify after
11// p.Name = "Bob"; // Error!

Required Properties (C# 11+)

Must be set during initialization:

csharp
1class Person
2{
3 public required string Name { get; set; }
4 public required int Age { get; set; }
5}
6
7// Must provide values
8Person p = new Person { Name = "Alice", Age = 25 }; // OK
9
10// Person p2 = new Person { Name = "Bob" }; // Error! Age is required

Fields vs Properties

AspectFieldsProperties
Syntaxpublic int Age;public int Age { get; set; }
ValidationNoYes (in setter)
Computed valuesNoYes (in getter)
EncapsulationBreaks itSupports it
Best practicePrivate onlyPublic access

Guideline

  • Use private fields for internal storage
  • Use properties for public access
  • Prefer auto-properties unless you need validation

Practical Example

csharp
1class Employee
2{
3 // Private fields
4 private decimal _salary;
5
6 // Auto-properties
7 public int Id { get; private set; }
8 public string Name { get; set; }
9 public string Department { get; set; }
10
11 // Property with validation
12 public decimal Salary
13 {
14 get => _salary;
15 set
16 {
17 if (value < 0)
18 throw new ArgumentException("Salary cannot be negative");
19 _salary = value;
20 }
21 }
22
23 // Computed properties
24 public decimal MonthlySalary => Salary / 12;
25 public decimal WeeklySalary => Salary / 52;
26
27 // Constructor
28 public Employee(int id, string name)
29 {
30 Id = id;
31 Name = name;
32 Department = "Unassigned";
33 Salary = 0;
34 }
35
36 public void DisplayInfo()
37 {
38 Console.WriteLine($"Employee #{Id}: {Name}");
39 Console.WriteLine($"Department: {Department}");
40 Console.WriteLine($"Annual Salary: {Salary:C}");
41 Console.WriteLine($"Monthly: {MonthlySalary:C}");
42 }
43}
44
45// Usage
46Employee emp = new Employee(1, "Alice");
47emp.Department = "Engineering";
48emp.Salary = 75000;
49emp.DisplayInfo();

Summary

In this lesson, you learned:

  • Fields are variables stored in a class
  • Properties provide controlled access with getters and setters
  • Auto-properties simplify common cases
  • Use private setters for read-only (from outside) properties
  • Validation logic belongs in property setters
  • Computed properties calculate values from other data
  • Prefer properties over public fields

Next, we'll learn about constructors for initializing objects.