Method Parameters
Parameters define the input a method expects. They are one of the most important parts of method design because they shape how callers interact with the method.
When you read a method signature, parameters answer questions such as:
- What information does this method need?
- Can the method change the caller's variable?
- Is the input required or optional?
- Does the API feel simple or awkward to call?
Good parameter design makes a method predictable at the call site.
Parameters versus arguments
A parameter is the name in the method declaration. An argument is the actual value passed by the caller.
static int Add(int left, int right)
{
return left + right;
}
int sum = Add(3, 4);In this example:
leftandrightare parameters3and4are arguments
That vocabulary matters because method design happens in terms of parameters, while method usage happens in terms of arguments.
Parameter flow at a glance
flowchart LR
A["Caller values"] --> B["Arguments at call site"]
B --> C["Parameters in method signature"]
C --> D["Method body uses those values"]
D --> E["Method returns result or causes effect"]In the most common case, the caller passes values in, and the method works with its own local parameter variables.
Value parameters
By default, C# passes arguments by value.
static void PrintDouble(int number)
{
number *= 2;
Console.WriteLine(number);
}
int value = 10;
PrintDouble(value);
Console.WriteLine(value);This prints 20 inside the method, but value remains 10 afterward.
That is because the method received its own copy of the value parameter.
For value types, this often means the caller's original variable is not changed.
ref parameters
ref passes a variable by reference, which means the method can work with the caller's actual variable rather than a separate copy.
static void Increment(ref int value)
{
value++;
}
int count = 5;
Increment(ref count);
Console.WriteLine(count);This prints 6 because the method changed the caller's variable directly.
Notice that ref must appear in both places:
- in the method declaration
- at the call site
That explicit syntax is important because it makes the stronger behavior visible.
out parameters
out parameters are used when a method needs to assign a value back through a parameter.
static bool TryGetDiscount(string customerType, out decimal rate)
{
if (customerType == "Premium")
{
rate = 0.15m;
return true;
}
rate = 0m;
return false;
}An out parameter must be assigned inside the method before the method returns.
This style is common in APIs such as TryParse:
if (int.TryParse("42", out int number))
{
Console.WriteLine(number);
}in parameters
in passes an argument by reference for reading only.
static decimal CalculateTax(in decimal price, in decimal rate)
{
return price * rate;
}This can be useful in more advanced scenarios, especially with larger value types, but beginners should mainly remember the intent: the method can read the value without being allowed to reassign it.
params parameters
params lets callers supply a variable number of arguments.
static int Sum(params int[] values)
{
int total = 0;
foreach (int value in values)
{
total += value;
}
return total;
}
Console.WriteLine(Sum(1, 2, 3, 4));This is useful when a method naturally accepts “zero or more” values.
A worked example
Suppose you want a method that updates an account balance and also reports the new value.
static bool TryWithdraw(ref decimal balance, decimal amount, out decimal remainingBalance)
{
if (amount <= 0 || amount > balance)
{
remainingBalance = balance;
return false;
}
balance -= amount;
remainingBalance = balance;
return true;
}
decimal balance = 250m;
if (TryWithdraw(ref balance, 40m, out decimal updatedBalance))
{
Console.WriteLine($"Withdrawal successful. Remaining: {updatedBalance:C}");
}This example shows why parameter design matters:
ref balancemeans the caller's balance can changeamountis a normal input parameterout decimal updatedBalancereports a result through a second output channel- the
boolreturn value tells the caller whether the operation succeeded
Even when this is technically valid, you should still ask whether the API is the clearest possible design.
Parameter design guidance
Prefer the simplest parameter style that expresses the intent.
- use normal value parameters by default
- use
refonly when caller state truly needs to be modified - use
outwhen the method naturally follows a “try/get” pattern - use
paramswhen a variable number of inputs improves usability
Do not add advanced parameter modifiers just because the syntax exists.
Common mistakes
- Confusing parameters with arguments.
- Using
refwhen returning a value would make the API clearer. - Forgetting that
refandoutmust be visible at the call site too. - Making a method signature so complicated that callers struggle to understand it.
Summary
Parameters define how data enters or leaves a method.
The main ideas are:
- normal parameters are passed by value by default
refallows direct modification of a caller variableoutis used for output assignment patternsinsupports read-only by-reference inputparamssupports variable-length argument lists
Good parameter design makes a method easier to call correctly.
Practice
Write a method that takes two decimal parameters and returns their average.
As a second exercise, write a small TryParse-style method that returns bool and uses an out parameter to provide a parsed result.