Skip to content

Methods, parameters and overloading

↑

Examples are independent C# snippets for modern .NET console projects unless noted otherwise. Class declarations and top-level code can live in Program.cs when top-level statements come first.

A method names a reusable operation. Its signature tells callers which arguments are required; return types communicate what the operation produces.

A parameter is declared by the method; an argument is supplied by the caller. Use void when nothing is returned, or a suitable type when the caller needs a result.

Example.cs
static int Add(int left, int right)
{
return left + right;
}
Console.WriteLine(Add(2, 3)); // 5

An optional parameter has a default value and can be omitted. Named arguments improve clarity when several arguments of the same type might otherwise be confused.

Example.cs
static string Label(string name, int level = 1)
=> $"{name} (level {level})";
Console.WriteLine(Label("Alex"));
Console.WriteLine(Label(level: 3, name: "Sam"));

Methods can share a name if their parameter lists differ. Return type alone cannot distinguish overloads. Keep overloads consistent in meaning so callers are not surprised.

Example.cs
Console.WriteLine(NumberMath.Double(4));
Console.WriteLine(NumberMath.Double(1.5));
public static class NumberMath
{
public static int Double(int number) => number * 2;
public static double Double(double number) => number * 2;
}

Deep dive: a method is a contract with its caller

Section titled “Deep dive: a method is a contract with its caller”

A parameter is the variable declared in a method signature; an argument is the expression supplied at the call site. The return type specifies what the caller receives. void means the method produces no return value, not that it cannot change state. A method should have a clear responsibility and a name that describes it.

Program.cs
Console.WriteLine(ScoreRules.CalculateBonus(score: 80, multiplier: 1.5)); // 120
public static class ScoreRules
{
public static int CalculateBonus(int score, double multiplier = 1)
{
if (score < 0 || multiplier < 0)
throw new ArgumentOutOfRangeException();
return (int)Math.Round(score * multiplier);
}
}

score and multiplier are parameters. The expressions 80 and 1.5 are arguments, shown with named-argument syntax. The optional parameter has a compile-time default; callers may omit it. Keep in mind that Math.Round has defined midpoint behavior, which may matter when calculating scores.

C# normally passes arguments by value. An int is copied, while a class reference is copied; therefore a method can mutate the object through the copied reference. ref and out make a variable itself accessible to the callee, with distinct initialization rules. Use out when a method needs to return a boolean success flag and a parsed result, as with int.TryParse.

Two methods can share a name if their parameter lists differ. This is overloading, not overriding. The compiler selects a matching overload using argument types, conversions and optional parameters. You cannot create overloads distinguished only by return type, and ambiguous numeric conversions can produce compile-time errors.

A calculation method is easier to test when it depends on its parameters and returns a result. A method that also writes to a file, changes a static counter or modifies global game state has side effects that callers need to understand. Separate pure calculations from I/O or state changes where it improves clarity; static alone does not guarantee purity.

Extract a method when an operation has a clear name, can be tested independently or is reused.

A void method cannot return a result value. Avoid overloads whose behavior changes unexpectedly depending on implicit numeric conversions.

Write IsAdult(int age) returning a boolean. Call it with a named argument.

Reveal a solution

static bool IsAdult(int age) => age >= 18; IsAdult(age: 20);.