C# 方法与参数传递

9.1 方法定义

基本语法

1
2
3
4
5
访问修饰符 返回类型 方法名 (参数列表)
{
// 方法体
return 返回值;
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 无参数无返回值
void SayHello()
{
Console.WriteLine("Hello!");
}

// 有参数有返回值
int Add(int a, int b)
{
return a + b;
}

// 调用方法
SayHello();
int result = Add(3, 5); // 8

9.2 参数传递

值参数(默认)

1
2
3
4
5
6
7
8
void Modify(int x)
{
x = 100; // 只修改副本
}

int a = 10;
Modify(a);
Console.WriteLine(a); // 10(不变)

ref 参数(引用传递)

1
2
3
4
5
6
7
8
9
10
void Swap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}

int x = 10, y = 20;
Swap(ref x, ref y);
Console.WriteLine($"x={x}, y={y}"); // x=20, y=10

out 参数(输出参数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void GetMinMax(int[] numbers, out int min, out int max)
{
min = numbers[0];
max = numbers[0];

foreach (int n in numbers)
{
if (n < min) min = n;
if (n > max) max = n;
}
}

int[] nums = { 5, 2, 8, 1, 9 };
GetMinMax(nums, out int min, out int max);
Console.WriteLine($"最小: {min}, 最大: {max}");

TryParse 模式

1
2
3
4
5
6
7
8
9
bool TryParseInt(string input, out int result)
{
return int.TryParse(input, out result);
}

if (TryParseInt("123", out int value))
{
Console.WriteLine($"解析成功: {value}");
}

9.3 in 参数(C# 7.2+)

1
2
3
4
5
6
7
8
9
10
11
12
13
// in 参数只读引用,避免复制大结构体
void PrintPoint(in Point p)
{
Console.WriteLine($"({p.X}, {p.Y})");
}

struct Point
{
public int X, Y;
}

Point p = new Point { X = 10, Y = 20 };
PrintPoint(in p);

9.4 方法重载

定义重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 同名不同参数
int Add(int a, int b)
{
return a + b;
}

double Add(double a, double b)
{
return a + b;
}

int Add(int a, int b, int c)
{
return a + b + c;
}

// 调用
Console.WriteLine(Add(1, 2)); // 3
Console.WriteLine(Add(1.5, 2.5)); // 4.0
Console.WriteLine(Add(1, 2, 3)); // 6

重载规则

1
2
3
4
5
6
7
8
9
10
11
// 合法重载:参数类型不同
void Process(int x) { }
void Process(string x) { }

// 合法重载:参数数量不同
void Process(int x) { }
void Process(int x, int y) { }

// 非法重载:仅返回类型不同
// int GetValue() { return 1; }
// string GetValue() { return "a"; } // 错误

9.5 可选参数

1
2
3
4
5
6
7
8
void Greet(string name, string greeting = "Hello")
{
Console.WriteLine($"{greeting}, {name}!");
}

Greet("Alice"); // Hello, Alice!
Greet("Bob", "Hi"); // Hi, Bob!
Greet("Charlie", greeting: "Hey"); // Hey, Charlie!

注意事项

1
2
3
4
5
6
7
8
// 可选参数必须在最后
void Method(int required, int optional = 10) { }

// 多个可选参数
void Configure(string name, int age = 18, string city = "Unknown") { }

// 调用时跳过中间参数
Configure("Alice", city: "Beijing");

9.6 命名参数

1
2
3
4
5
6
7
8
9
10
11
12
13
void CreateUser(string name, int age, string email)
{
Console.WriteLine($"{name}, {age}, {email}");
}

// 传统调用
CreateUser("Alice", 25, "alice@example.com");

// 命名参数(顺序可变)
CreateUser(age: 25, email: "alice@example.com", name: "Alice");

// 混合使用
CreateUser("Alice", email: "alice@example.com", age: 25);

9.7 局部函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void ProcessData()
{
// 局部函数
int Calculate(int x, int y)
{
return x + y;
}

int result = Calculate(3, 5);
Console.WriteLine(result);
}

// 递归局部函数
int Factorial(int n)
{
return n <= 1 ? 1 : n * Factorial(n - 1);
}

9.8 表达式体方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 传统写法
int Add(int a, int b)
{
return a + b;
}

// 表达式体(C# 6+)
int Add(int a, int b) => a + b;

// void 方法
void Print(string msg) => Console.WriteLine(msg);

// 条件表达式
string GetStatus(bool isActive) => isActive ? "活跃" : "禁用";

9.9 方法最佳实践

1. 单一职责

1
2
3
4
5
6
7
// 不推荐:一个方法做太多事
void ProcessAndSaveAndNotify(User user) { }

// 推荐:拆分职责
void ProcessUser(User user) { }
void SaveUser(User user) { }
void NotifyUser(User user) { }

2. 参数数量

1
2
3
4
5
6
7
8
9
10
11
12
// 不推荐:参数过多
void CreateUser(string name, int age, string email, string phone, string address) { }

// 推荐:使用对象封装
class UserConfig
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}

void CreateUser(UserConfig config) { }

3. 命名规范

1
2
3
4
5
6
7
8
// 方法名使用 PascalCase
public void CalculateTotal() { }
public int GetUserId() { }

// 布尔方法用 Is/Has/Can 开头
public bool IsValid() { }
public bool HasPermission() { }
public bool CanEdit() { }

9.10 本章小结

  • 方法由访问修饰符、返回类型、名称、参数组成
  • 值参数复制值,ref/out 传递引用
  • out 参数必须在方法内赋值
  • 方法重载通过参数类型/数量区分
  • 可选参数和命名参数提高调用灵活性
  • 局部函数用于辅助逻辑
  • 表达式体简化简单方法

练习题

  1. 编写方法计算数组平均值
  2. 使用 out 参数实现除法(返回商和余数)
  3. 创建重载方法支持不同参数类型
  4. 以下代码输出什么?
    1
    2
    3
    4
    void Modify(ref int x) { x = 100; }
    int a = 10;
    Modify(ref a);
    Console.WriteLine(a);
ByteFisher
分享编程技术 · 记录钓鱼乐趣
扫码关注
▸ 扫码关注 ◂
C#基础教程 系列
第 9/20 篇
分享: