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:
csharp1class Person2{3 public string name; // Field4 public int age; // Field5 private decimal salary; // Private field6}
Field Naming Convention
csharp1class Example2{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:
csharp1class Person2{3 public int Age;4}56Person 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:
csharp1class Person2{3 private int _age; // Private backing field45 public int Age6 {7 get { return _age; }8 set9 {10 if (value >= 0 && value <= 150)11 {12 _age = value;13 }14 }15 }16}1718Person p = new Person();19p.Age = 25; // Calls the setter20int a = p.Age; // Calls the getter
Property Syntax
Full Property (with backing field)
csharp1class Person2{3 private string _name;45 public string Name6 {7 get { return _name; }8 set { _name = value; }9 }10}
Auto-Implemented Property
When you don't need validation, use auto-properties:
csharp1class Person2{3 public string Name { get; set; } // Compiler creates backing field4 public int Age { get; set; }5}
Expression-Bodied Properties
csharp1class Person2{3 private string _name;45 public string Name6 {7 get => _name;8 set => _name = value;9 }10}
Read-Only Properties
Get-Only Auto-Property
csharp1class Circle2{3 public double Radius { get; } // Can only be set in constructor45 public Circle(double radius)6 {7 Radius = radius;8 }9}
Calculated Property (no setter)
csharp1class Circle2{3 public double Radius { get; set; }45 public double Area6 {7 get { return Math.PI * Radius * Radius; }8 }910 // Or using expression body11 public double Circumference => 2 * Math.PI * Radius;12}
Property Initializers
Set default values:
csharp1class Person2{3 public string Name { get; set; } = "Unknown";4 public int Age { get; set; } = 0;5 public bool IsActive { get; set; } = true;6}78Person p = new Person();9Console.WriteLine(p.Name); // "Unknown"
Private Setters
Allow reading from outside, but only setting from within the class:
csharp1class BankAccount2{3 public string AccountNumber { get; private set; }4 public decimal Balance { get; private set; }56 public BankAccount(string number)7 {8 AccountNumber = number;9 Balance = 0;10 }1112 public void Deposit(decimal amount)13 {14 if (amount > 0)15 {16 Balance += amount; // Can set from inside17 }18 }19}2021// Usage22BankAccount account = new BankAccount("12345");23Console.WriteLine(account.Balance); // Can read24// account.Balance = 1000; // Error! Cannot set from outside25account.Deposit(100); // This works
Validation in Setters
csharp1class Product2{3 private string _name;4 private decimal _price;56 public string Name7 {8 get => _name;9 set10 {11 if (string.IsNullOrWhiteSpace(value))12 throw new ArgumentException("Name cannot be empty");13 _name = value.Trim();14 }15 }1617 public decimal Price18 {19 get => _price;20 set21 {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:
csharp1class Person2{3 public string Name { get; init; }4 public int Age { get; init; }5}67// Can set during initialization8Person p = new Person { Name = "Alice", Age = 25 };910// Cannot modify after11// p.Name = "Bob"; // Error!
Required Properties (C# 11+)
Must be set during initialization:
csharp1class Person2{3 public required string Name { get; set; }4 public required int Age { get; set; }5}67// Must provide values8Person p = new Person { Name = "Alice", Age = 25 }; // OK910// Person p2 = new Person { Name = "Bob" }; // Error! Age is required
Fields vs Properties
| Aspect | Fields | Properties |
|---|---|---|
| Syntax | public int Age; | public int Age { get; set; } |
| Validation | No | Yes (in setter) |
| Computed values | No | Yes (in getter) |
| Encapsulation | Breaks it | Supports it |
| Best practice | Private only | Public access |
Guideline
- Use private fields for internal storage
- Use properties for public access
- Prefer auto-properties unless you need validation
Practical Example
csharp1class Employee2{3 // Private fields4 private decimal _salary;56 // Auto-properties7 public int Id { get; private set; }8 public string Name { get; set; }9 public string Department { get; set; }1011 // Property with validation12 public decimal Salary13 {14 get => _salary;15 set16 {17 if (value < 0)18 throw new ArgumentException("Salary cannot be negative");19 _salary = value;20 }21 }2223 // Computed properties24 public decimal MonthlySalary => Salary / 12;25 public decimal WeeklySalary => Salary / 52;2627 // Constructor28 public Employee(int id, string name)29 {30 Id = id;31 Name = name;32 Department = "Unassigned";33 Salary = 0;34 }3536 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}4445// Usage46Employee 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.