C# Foundations · Lesson 9

Methods

A method names a calculation so another line can call it.

A method gives one calculation a named contract

A method or local function packages behavior behind a name, parameter list, and return type. Here TotalOf promises to accept two decimal values and return a decimal value. A call supplies arguments for those parameters. The implementation can use the parameter names without knowing which variables or literals the caller used. This boundary is valuable because the same calculation can be requested several times without copying its body or mixing its details into each reporting statement.

The declaration in this top-level program is a local function. Writing its body does not execute the addition immediately; execution happens when the call is reached. The return value and the output operation are separate concepts. return a + b sends a numeric result to the caller, while Console.WriteLine presents that result. This separation makes the calculation usable in a larger expression, in another function, or in a test that compares values without scraping console text.

Follow arguments into parameters and the result back out

The call is TotalOf(12m, 25m). Its first argument becomes the parameter a and its second becomes b for this invocation. The body evaluates their decimal sum and returns thirty-seven. Control then resumes at the calling expression, where WriteLine receives that returned decimal. The original sample prints exactly one line, 37. It does not print the parameter names, the method declaration, or a separate result for each argument.

There is no assignment to either parameter and no hidden change to a caller variable. Decimal values are passed by value here, and the function merely reads them. The same function can therefore be called again with a different pair without retaining a previous total. That repeatability follows from this implementation's lack of external state, not from an automatic guarantee attached to every method. Another method could read global state, mutate an object, or produce output, so inspect the actual body and contract.

decimal TotalOf(decimal a, decimal b)
{
    return a + b;
}

A returned value is not an automatic print instruction

Calling TotalOf(12m, 25m); by itself computes a result that the statement then discards. If you remove WriteLine and see no output, that is not evidence that the function failed to run. Conversely, adding WriteLine inside TotalOf changes its observable responsibilities and can produce duplicate lines when the caller also prints. Keep the calculation separate unless printing is genuinely its contract. Also keep decimal arguments explicit: an unrelated type mismatch should be resolved by deciding the intended numeric domain, not by guessing casts.

Reuse the result in two different ways

First store the call in a variable named subtotal, then print subtotal twice. Predict two identical lines of 37, with one calculation supplying both observations. Change the first argument to 2m and predict 27 without editing the function. Hint: distinguish the local name used by the caller from parameter a; they do not need to match. Add a second call with 0m and 5m to check a useful simple boundary.

Next compose two calls: calculate the total of TotalOf(12m, 25m) and 3m. The expected result is forty. Hint: evaluate the innermost call first and substitute its returned value into the outer call. Then write an independent DifferenceOf function and decide whether argument order matters. Compare both functions' contracts, including whether negative values are acceptable, rather than assuming every two-parameter calculation behaves like addition.

Describe the boundary, not only the syntax

Explain what callers supply, what the function returns, and what it does not modify in this example. You should be able to use the returned decimal without printing it and to predict multiple calls independently. When extracting a method from a longer program, choose a name and parameter list that reveal the calculation's meaning. Then test its result separately from formatting so a presentation change cannot disguise a broken calculation.

  • The parameters and return value are all decimal values.
  • Declaring the function does not execute a call.
  • The original caller prints the returned value 37.
  • Discarding a return value produces no automatic console output.

A working example

decimal TotalOf(decimal a, decimal b)
{
    return a + b;
}
Console.WriteLine(TotalOf(12m, 25m));

Expected output

37
Try this
Name the inputs, then return the result.

Further reading