Csharp Methods
# C# Methods
## C# Methods
A method is a block of code that groups related statements together to perform a specific task. It is the core mechanism in C# for achieving **code reuse** and **logical encapsulation**. Every C# program has at least one `Main` method as its entry point.
Using methods involves two steps: **defining a method** and **calling a method**.
* * *
## 1. Defining a Method
The basic syntax for defining a method in C# is as follows:
() { method body }
A method consists of the following elements:
* **Access Modifier**: Controls the visibility of the method, such as `public`, `private`, `protected`, `internal`.
* **Return Type**: The data type of the value returned by the method. If the method does not return any value, use `void`.
* **Method Name**: The unique identifier for the method, following PascalCase naming conventions (e.g., `FindMax`, `GetUserName`).
* **Parameter List**: The inputs the method receives, enclosed in parentheses. Parameters are optional; a method can have no parameters.
* **Method Body**: Contains the code that implements the functionality, enclosed in curly braces `{}`.
The following diagram illustrates the complete structure of a method:
### 1.1 First Method Example
The following defines a `FindMax` method that takes two integers and returns the larger one:
## Example
using System;
namespace MethodDemo
{
class NumberHelper
{
// Define a method: takes two ints, returns the larger one
public int FindMax(int num1, int num2)
{
if(num1 > num2)
return num1;
else
return num2;
}
static void Main(string[] args)
{
// Create an object and call the method
NumberHelper helper =new NumberHelper();
int result = helper.FindMax(100, 200);
Console.WriteLine($"The maximum value is: {result}");// The maximum value is: 200
}
}
}
**Method Call Flow:**
> **Cross-class Call:** As long as a method is declared as `public`, it can be called from other classes by creating an instance. This is the foundation of code reuse in object-oriented programming.
* * *
## 2. Parameter Passing Methods
C# provides three ways to pass parameters to methods. The core difference lies in **whether they share memory**:
| Method | Keyword | Behavior | Typical Scenario |
| --- | --- | --- | --- |
| Pass by Value | (none) | Copies the parameter value; modifications inside the method do not affect the original variable | Most method calls (default) |
| Pass by Reference | `ref` | Passes the reference (memory address) of the variable; modifications inside the method change the original variable | When you need to modify an external variable (e.g., swapping values) |
| Output Parameter | `out` | Similar to ref, but the method must assign a value; no initialization required before calling | When a method needs to return multiple values |
### 2.1 Pass by Value (Default)
Pass by value is the default method. The value of the actual parameter is **copied** to the formal parameter. Modifications to the formal parameter inside the method do not affect the original variable:
## Example
using System;
namespace ParameterDemo
{
class Program
{
// Pass by value: x and y are copies of a and b
public void Swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
Console.WriteLine($"Inside method: x={x}, y={y}");// Swap successful
}
static void Main(string[] args)
{
var p =new Program();
int a =100, b =200;
Console.WriteLine($"Before call: a={a}, b={b}");
p.Swap(a, b);
Console.WriteLine($"After call: a={a}, b={b}");// a and b are unchanged!
}
}
}
Before call: a=100, b=200 Inside method: x=200, y=100After call: a=100, b=200
### 2.2 Pass by Reference (ref)
Using the `ref` keyword passes the **reference** (memory address) of the variable. Modifications to the formal parameter inside the method directly affect the original variable. Note that `ref` must also be used when calling the method:
## Example
using System;
namespace ParameterDemo
{
class Program
{
// Reference pass: x and y directly reference the memory of a and b
public void Swap(ref int x, ref int y)
{
int temp = x;
x = y;
y = temp;
}
static void Main(string[] args)
{
var p =new Program();
int a =100, b =200;
Console.WriteLine($"Before call: a={a}, b={b}");
p.Swap(ref a, ref b);// Must also add ref when calling
Console.WriteLine($"After call: a={a}, b={b}");// Swap successful!
}
}
}
Before call: a=100, b=200After call: a=200, b=100
> **Difference between ref and out:** `ref` requires the variable to be **initialized before passing**; `out` does not, but the method **must assign a value to the out parameter** before using it.
### 2.3 Output Parameter (out)
The `out` parameter allows a method to **return multiple values**. Unlike `ref`, the variable does not need to be initialized before calling, but the method must assign a value to it:
## Example
using System;
namespace ParameterDemo
{
class Program
{
// out parameter: the method is responsible for assignment
public void GetValues(out int x, out int y)
{
Console.Write("Enter the first value: ");
x = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the second value: ");
y = Convert.ToInt32(Console.ReadLine());
// Note: All out parameters must be assigned before the method ends, otherwise a compilation error occurs
}
// Practical example: TryParse pattern
public bool TryDivide(int a, int b, out double result)
{
if(b ==0)
{
result =0;
return false;// Divisor is zero
}
result =(double)a / b;
return true;
}
static void Main(string[] args)
{
var p =new Program();
// out parameters do not need initialization
int a, b;
p.GetValues(out a, out b);
Console.WriteLine($"a={a}, b={b}");
// TryParse pattern
if(p.TryDivide(10, 3, out double res))
Console.WriteLine($"10 / 3 = {res:F2}");// 3.33
}
}
}
Starting from C# 7.0, you can **declare out variables inline** when calling, making the code more concise:
// C# 7.0+ inline declarationif (int.TryParse("123", out int number)) Console.WriteLine($"Parsed successfully: {number}");
* * *
## 3. Recursive Methods
Recursion refers to a method **calling itself**. Every recursive method requires two elements:
* **Base Case**: The condition that terminates the recursion, preventing infinite recursion.
* **Recursive Step**: Breaks the problem down into smaller subproblems.
Classic exampleβcalculating factorial $$n! = n times (n-1)!$$:
## Example
using System;
namespace RecursionDemo
{
class Program
{
// Recursively calculate factorial
public int Factorial(int n)
{
// Base case: 0! = 1, 1! = 1
if(n **Note:** Excessive recursion depth can cause a `StackOverflowException`. For performance-sensitive scenarios, consider using a loop instead.
* * *
## 4. More Method Features
### 4.1 Default Parameters and Named Arguments
C# allows setting **default values** for parameters, which can be omitted when calling the method. Combined with **named arguments**, you can skip certain parameters and only specify the ones that follow:
## Example
using System;
namespace MethodFeatures
{
class Program
{
// Default parameter: power defaults to 2
static double Power(double baseNum, int power =2)
{
double result =1;
for(int i =0; i ` (C# 6.0+):
// Traditional syntaxpublic int Add(int a, int b){ return a + b;}// Expression-bodied syntax (equivalent)public int Add(int a, int b) => a + b;
### 4.3 Method Overloading
A class can have **multiple methods with the same name** as long as their parameter lists differ (different parameter types, number, or order):
## Example
using System;
namespace MethodFeatures
{
class Calculator
{
// Overload 1: add two ints
public int Add(int a, int b)=> a + b;
// Overload 2: add three ints
public int Add(int a, int b, int c)=> a + b + c;
// Overload 3: add two doubles
public double Add(double a, double b)=> a + b;
static void Main(string[] args)
{
var calc =new Calculator();
Console.WriteLine(calc.Add(1, 2));// 3 (calls overload 1)
Console.WriteLine(calc.Add(1, 2, 3));// 6 (calls overload 2)
Console.WriteLine(calc.Add(1.5, 2.5));// 4.0 (calls overload 3)
}
}
}
* * *
## Summary
| Feature | Syntax | Description |
| --- | --- | --- |
| Define a Method | `int Add(int a, int b) { ... }` | Specifies return type, method name, and parameters |
| No Return Value | `void DoSomething() { ... }` | `void` indicates no value is returned |
| Pass by Value | `void Foo(int x)` | Default method; modifying the formal parameter does not affect the actual parameter |
| Pass by Reference | `void Foo(ref int x)` | Shares memory; modifications reflect in the actual parameter |
| Output Parameter | `void Foo(out int x)` | Must be assigned inside the method; can return multiple values |
| Default Parameter | `void Foo(int x = 10)` | Can be omitted when calling; uses the default value |
| Named Argument | `Foo(city: "Beijing")` | Specifies parameters by name; can be out of order |
| Expression Body | `int Add(int a, int b) => a + b;` | Shorthand for single-line methods (C# 6.0+) |
| Method Overloading | Same name, different parameters | The compiler automatically selects based on the parameter list |
YouTip