Menu
Coddy logo textTech

Properties for Encapsulation

Part of the Object Oriented Programming section of Coddy's C# journey — lesson 32 of 70.

Properties are the primary tool for implementing encapsulation in C#. Instead of exposing fields directly, you wrap them with properties that control how data is accessed and modified.

The pattern combines a private field with a public property that includes validation or logic in its accessors:

public class Temperature
{
    private double celsius;
    
    public double Celsius
    {
        get { return celsius; }
        set
        {
            if (value < -273.15)
                celsius = -273.15;  // Absolute zero minimum
            else
                celsius = value;
        }
    }
}

Now external code can't set an impossible temperature. The property acts as a gatekeeper, ensuring your object always stays in a valid state. This is encapsulation in action - the internal data is protected while still being accessible through a controlled interface.

You can also use properties to compute values or trigger side effects:

public double Fahrenheit
{
    get { return celsius * 9 / 5 + 32; }
    set { celsius = (value - 32) * 5 / 9; }
}

The outside world sees two properties, but internally there's only one field. Properties let you change implementation details without breaking code that uses your class - a key benefit of proper encapsulation.

challenge icon

Challenge

Easy

Let's build a product inventory system that uses properties to protect data integrity. You'll create a class where prices can never go negative and quantities are always kept within valid bounds - demonstrating how properties act as gatekeepers for your data.

You'll organize your code across two files:

  • Product.cs: Create a Product class in the Inventory namespace that manages product information with validation through properties. Your product needs:
    • A private field price (decimal) with a public Price property that ensures the price never goes below 0 - if someone tries to set a negative price, it should be stored as 0 instead
    • A private field quantity (int) with a public Quantity property that keeps values between 0 and 1000 - values below 0 become 0, values above 1000 become 1000
    • A public auto-implemented property Name (string)
    • A computed read-only property TotalValue that returns Price * Quantity
    Include a constructor that accepts name, price, and quantity (in that order) and sets all values through the properties so validation is applied.
  • Program.cs: In your main file, create a Product using input values. Then attempt to modify the price and quantity with additional input values that might be invalid. Print the product's state after creation and after each modification to see how the properties protect the data.

You will receive five inputs:

  • Product name
  • Initial price (decimal)
  • Initial quantity (integer)
  • New price to set (decimal, might be negative)
  • New quantity to set (integer, might be out of range)

Print the output in this format:

After creation:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
After modifications:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}

For example, if the inputs are Laptop, 999.99, 50, -100, and 1500, the output should be:

After creation:
Laptop: Price=999.99, Qty=50, Total=49999.50
After modifications:
Laptop: Price=0, Qty=1000, Total=0

Notice how the negative price became 0 and the quantity of 1500 was clamped to 1000. Your properties are protecting the object from invalid states - this is encapsulation at work!

Cheat sheet

Properties wrap private fields with controlled access through get and set accessors, enabling validation and encapsulation:

public class Temperature
{
    private double celsius;
    
    public double Celsius
    {
        get { return celsius; }
        set
        {
            if (value < -273.15)
                celsius = -273.15;
            else
                celsius = value;
        }
    }
}

Properties can compute values based on internal fields:

public double Fahrenheit
{
    get { return celsius * 9 / 5 + 32; }
    set { celsius = (value - 32) * 5 / 9; }
}

Read-only properties omit the set accessor, allowing only retrieval of computed or stored values.

Try it yourself

using System;
using Inventory;

class Program
{
    public static void Main(string[] args)
    {
        // Read inputs
        string name = Console.ReadLine();
        decimal initialPrice = Convert.ToDecimal(Console.ReadLine());
        int initialQuantity = Convert.ToInt32(Console.ReadLine());
        decimal newPrice = Convert.ToDecimal(Console.ReadLine());
        int newQuantity = Convert.ToInt32(Console.ReadLine());

        // TODO: Create a Product using the initial values
        
        // TODO: Print the product state after creation
        Console.WriteLine("After creation:");
        // Print format: {Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
        
        // TODO: Modify the price and quantity with the new values
        
        // TODO: Print the product state after modifications
        Console.WriteLine("After modifications:");
        // Print format: {Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming