Methods and Modularity
Packaging logic into named, reusable pieces — and the discipline of writing small, focused methods
A method is a named block of code that takes inputs, does something, and (optionally) returns a result. Methods are the basic unit of reuse in C#, and the practice of breaking a program into many small methods is the heart of what programmers mean by modularity.
If "a variable is a named box of data," then "a method is a named box of behavior."
A first method
Read the declaration left to right:
int— the method returns anint.Square— the method's name.(int x)— it takes one parameter namedxof typeint.{ return x * x; }— the body runs when the method is called.
Calling the method (Square(5)) takes its body, plugs in the
argument, and gives back a value you can use anywhere.
Parameters and arguments
A parameter is the name in the method's declaration; an argument is the actual value supplied at the call site. They match up in order.
The names a and b exist only inside Average. They
disappear the moment the method returns.
void methods: do something, return nothing
If a method doesn't need to return a value, its return type is
void.
void methods are usually about side effects: writing to the
console, modifying a file, mutating an object. A method that has
neither a return value nor a useful side effect doesn't do
anything at all.
A picture of a method call
Earlier we saw that each method call gets its own stack frame. That picture is worth pinning to the wall:
Inside Square, the variable x is just a name for the value 5.
When Square returns, that name disappears. If the caller had its
own variable named x, it would be unaffected.
Expression-bodied methods
A short method that's just return some expression; can be
written more compactly with =>:
Same meaning as the longer form, just less noise. Use whichever makes a particular method easier to read.
Why bother with methods at all?
Suppose you have to compute a Body Mass Index three times in your program. Without methods, you write the formula three times. With methods, you write it once.
Three reasons this is better than copy-pasting the formula three times:
- One place to fix bugs. If the formula is wrong, fix it once.
- Self-documenting.
Bmi(60, 1.65)reads like "BMI of 60 kg at 1.65 m." The raw arithmetic doesn't. - Easier to test. You can call
Bmi(...)from a test with known inputs and check the output, without running the whole program.
Defaults and named arguments
C# lets you declare defaults for parameters and let callers pass arguments by name, which makes intent clear at the call site.
level: "WARN" is much clearer than passing positional arguments
and hoping the reader remembers the parameter order. Use named
arguments when an argument might otherwise be cryptic (especially
booleans).
Method overloading
You can have multiple methods with the same name but different parameter lists. The compiler picks the right one based on the arguments you pass.
Use overloading sparingly — too many overloads can confuse readers. The common cases are:
- "Same operation on different primitive types."
- "Same operation with a default vs explicit configuration."
Modularity: small methods that do one thing
The single most useful habit you can build as a beginner is this:
When a method gets longer than ~20 lines, see if you can pull out a meaningfully-named smaller method.
Compare the two versions below.
Long, monolithic version
Modular version, same behavior
Each helper does exactly one thing. The summary method Describe
now reads almost like English. If we needed to test Sum alone,
we could.
Common method-design rules of thumb
- Name methods after what they do.
CalculateTax(...), notProcess(...). - Aim for one job per method. If you'd need an "and" to describe it, it's doing too much.
- Prefer returning a value over mutating shared state. Pure functions are easier to reason about.
- Limit parameters. Three is comfortable. Five is suspicious. Seven is a redesign.
- Don't repeat yourself. If the same code shows up twice, it belongs in a method.
Multi-file methods: organizing across files
Bigger programs split methods across multiple .cs files. Each
file usually contains one class (we'll meet classes in the next
section). The compiler builds them all together.
We'll dig into static, class, and public in the next chapter.
Just notice: methods live inside a class; multiple files combine
into one program; the call site MathUtils.Square(4) reads
naturally.
Practice
Build two methods on the static class Stats:
int Sum(int[] xs)returns the sum of the array.int Max(int[] xs)returns the maximum value (assume the array has at least one element).
Program.cs calls both with a fixed array and prints exactly:
sum=20
max=7
Test your understanding
What does the keyword void mean in a method declaration?
The method never runs
The method has no parameters
The method returns no value to the caller
The method is private
Why is "small methods doing one thing" a good habit?
Smaller methods compile faster
The language requires it
Small focused methods are easier to name, test, reuse, and reason about — and changes stay localized
Smaller methods use less memory