Course contentsShow
← C#
Lesson 209 of 1,9082. Object-Oriented Design in C#Free lesson

Command-Query Separation Principle

You will split state-changing operations from state-retrieval logic to improve system scalability and clarity.

In this lesson, you will learn how to improve the predictability of your code by strictly separating methods that change data from those that simply report on it.

The Problem: Mixing Concerns

In many C# classes, you might find a method that does two things: it performs an action (like updating a database) and returns a result. While this seems convenient, it creates "side effects." If you call a method just to see if an item is in stock, but that method also increments an "access count" or modifies a hidden variable, your system becomes unpredictable and hard to debug.

The Solution: Command-Query Separation (CQS)

The Command-Query Separation principle states that every method should be one of two things:

  1. A Command: Performs an action that changes the state of the system. Commands should return void. They do one thing and do it well.
  2. A Query: Returns data but does not change the state of the system. Queries should be side-effect-free; calling them a hundred times should never change the underlying object's data.

Practical Example

Imagine an InventoryManager class. Instead of a method that checks stock and marks it as "checked" in a log, we split them:

public class InventoryManager
{
    // COMMAND: Changes state, returns nothing
    public void RestockItem(string itemId, int amount) 
    {
        // Update database logic here
    }

    // QUERY: Returns data, does NOT change state
    public int GetStockCount(string itemId) 
    {
        return _database.FetchCount(itemId);
    }
}

By following this rule, developers using your class can safely call GetStockCount as often as they like without worrying about accidentally triggering a database update or changing a value in the background.

When your code strictly separates "doing" from "asking," your system becomes much easier to test, scale, and maintain because you always know exactly what a method is doing the moment you read its signature.

Key Takeaway: A method should either perform an action (Command) or return data (Query), but it should never do both.