If you do the same thing in multiple places, the answer is to group it in a method. A method is defined by name, parameters, and return value, and multiple methods can have the same name with different signatures (overloading).
Learning Objectives
- Understand method declaration and call flow
- Parameters and return types can be specified
- Know the meaning and rules of overloading
- Classify the use of keywords
out/ref/in - Use optional parameters and named arguments
Key concepts
1) Method declaration and call
static int Add(int a, int b) //return type parameter
{
return a + b;
}
int s = Add(3, 4); //call → 7
- If there is no return value, it is
void - If declared as
staticwithin top-level statements, it can be called from the same file.
2) Overloading
You can have multiple methods with the same name with different signature (parameter Quantity/Type). Different return types are not overloading.
static int Add(int a, int b) => a + b;
static double Add(double a, double b) => a + b;
int i = Add(1, 2); //int version
double d = Add(1.5, 2.5); //double version
3) out / ref / in
| Keyword | When entering | When it comes out | Use |
|---|---|---|---|
out |
No initialization required | Method must be assigned | "second return value" |
ref |
Reset required | Two-way | Modifying caller values directly |
in |
Reset required | read-only | Reduce copying costs of large structs |
if (int.TryParse("42", out int n)) // out
Console.WriteLine(n);
static void Swap(ref int a, ref int b) { (a, b) = (b, a); } // ref
static void Print(in Point p) { Console.WriteLine($"{p.X},{p.Y}"); } // in
When calling out/ref, the keyword must be rewritten: Swap(ref x, ref y);.
4) Optional parameters
It can be omitted by giving the last parameter a default value.
static void Greet(string name, string lang = "ko")
{
Console.WriteLine(lang == "ko" ? $"Hello, {name}!" : $"Hi, {name}!");
}
Greet("exponent"); //Hello, Jisoo!
Greet("Jisoo", "en"); // Hi, Jisoo!
5) Named arguments
If you specify arguments by name, they can be passed regardless of order. Useful for readability and skipping default values.
static void Order(string item, int qty = 1, bool gift = false) { /* ... */ }
Order(item: "apple", gift: true); //qty default value is 1, only gift is specified
See as example
Example 1 — Basic/Program.cs: Called separately as a method
static int Add(int a, int b)
{
return a + b;
}
int x = Add(3, 4);
int y = Add(10, 20);
Console.WriteLine($"Add(3, 4) = {x}");
Console.WriteLine($"Add(10,20) = {y}");
Execution result
Add(3, 4) = 7
Add(10,20) = 30
Note: In top-level statements files, it is common** to group methods **at the end of the file. (The current example is short so I placed it at the top.)
Example 2 — Overloading/Program.cs: same name, different signature
Console.WriteLine($"Calc.Add(1, 2) = {Calc.Add(1, 2)}");
Console.WriteLine($"Calc.Add(1.5, 2.5) = {Calc.Add(1.5, 2.5)}");
static class Calc
{
public static int Add(int a, int b) => a + b;
public static double Add(double a, double b) => a + b;
}
Execution result
Calc.Add(1, 2) = 3
Calc.Add(1.5, 2.5) = 4
Memo: => is an expression-bodied member — can be written neatly with one line of body. Local functions cannot be overloaded, so if you want to use the same name, you must wrap it in static class.
Example 3 — OutRefIn/Program.cs : Demonstrating out, ref, in
namespace CodingNow.Lecture.Basics05;
internal static class Program
{
public static void Main()
{
//out: TryParse pattern
if (int.TryParse("123", out int parsed))
Console.WriteLine($"Parsing succeeded: {parsed}");
//ref: Swap two values
int x = 1, y = 2;
Swap(ref x, ref y);
Console.WriteLine($"After Swap x={x}, y={y}");
//in: passing a read-only reference
Point p = new(10, 20);
Print(in p);
}
static void Swap(ref int a, ref int b)
{
(a, b) = (b, a);
}
static void Print(in Point p)
{
//p.X = 0; // Compilation error: in is read-only
Console.WriteLine($"Point({p.X}, {p.Y})");
}
}
internal readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) { X = x; Y = y; }
}
Execution result
Parse success: 123
After Swap x=2, y=1
Point(10, 20)
Memo: out int parsed declares variables at the same time at the call site. C# 7+ features.
Example 4 — OptionalNamed/Program.cs: Optional/named arguments
static void Order(string item, int qty = 1, bool gift = false)
{
string wrap = gift ? "(gift wrapping)" : "";
Console.WriteLine($"{item} × {qty}{wrap}");
}
Order("apple"); //default
Order("ship", 3); //specify qty
Order(item: "grapes", gift: true); //By name — qty defaults to 1
Order("Tangerine", qty: 5, gift: true);
Execution result
Apple × 1
Ship × 3
Grapes × 1 (gift wrapped)
Tangerine × 5 (gift wrapped)
Note: Optional parameters must always appear at the end. Centering it requires the caller to specify all of them as named arguments, which is inconvenient.
Common Mistakes
- The method name is the same, but only the return type is defined differently — Compilation error. The signature does not include a return type.
- Ending with no value given to the
outparameter in the method — compilation error. - Missing
ref/outkeywords when calling —Swap(ref x, ref y), notSwap(x, y). - Default to mutable object for optional parameters — only compile-time constants are allowed.
- Too long parameter list — If it exceeds 4-5, consider grouping it into an object.
Cleanup
- A method is a unit of input (parameters) → processing → output (return value).
- Overloading only works if the signatures are different**
outis "return extra",refis "two-way",inis "read-only reference"- Keep calling code clean with optional and named arguments
Try it yourself
cd src/Basic && dotnet run
cd ../Overloading && dotnet run
cd ../OutRefIn && dotnet run
cd ../OptionalNamed && dotnet run