定义
public int Add(int a, int b)
{
return a + b;
}
修饰符 + 返回类型 + 名称 + 参数列表 + 体。
返回 void 表示无返回值。
表达式体方法(C# 6+)
public int Add(int a, int b) => a + b;
单表达式用 => 一行写完。常见于属性、简单方法。
静态方法
public static class MathUtils
{
public static int Square(int x) => x * x;
}
// 调用
int n = MathUtils.Square(5); // 不需要实例
参数修饰符
void Inc(int x) { x++; } // 值传递(默认)
void IncRef(ref int x) { x++; } // 按引用:调用方变量也变
void IncOut(out int x) { x = 10; } // 必须在方法内赋值
void Read(in MyStruct x) { ... } // 只读引用(避免大 struct 复制)
int n = 5;
IncRef(ref n); // 必须显式 ref
IncOut(out int m); // 必须显式 out,可以 inline 声明
// 传 in:调用时省略,但推荐写以明确
Read(in big);
可选参数
void Greet(string name, string greeting = "Hello")
{
Console.WriteLine($"{greeting}, {name}");
}
Greet("Alice"); // Hello, Alice
Greet("Bob", "Hi"); // Hi, Bob
Greet("Charlie", greeting: "Howdy"); // 命名实参
可选参数必须在必选之后。
命名实参
SendEmail(to: "a@x.com", subject: "Hi", body: "Hello");
SendEmail(body: "Hello", to: "a@x.com", subject: "Hi"); // 顺序可换
参数多时大幅提升可读性——File.Open("data.txt", FileMode.Open, FileAccess.Read) vs File.Open("data.txt", access: FileAccess.Read, mode: FileMode.Open)。
params:变长参数
public static int Sum(params int[] nums)
{
int total = 0;
foreach (var n in nums) total += n;
return total;
}
Sum(1, 2, 3); // 6
Sum(1, 2, 3, 4, 5); // 15
Sum(); // 0(空数组)
Sum(new[] { 1, 2 }); // 也能直接传数组
params 必须是最后一个参数。一个方法最多一个 params。
重载(同名多版本)
public int Add(int a, int b) => a + b;
public double Add(double a, double b) => a + b;
public string Add(string a, string b) => a + b;
C# 按参数类型 / 数量自动选——叫重载分辨。
注意:只有返回类型不同不是重载——会编译错误。
表达式 vs 语句方法体
// 语句体
public int Sum(int[] arr)
{
int total = 0;
foreach (var n in arr) total += n;
return total;
}
// 表达式体(一行能写完时)
public int Sum(int[] arr) => arr.Sum();
局部函数
public int Solve(int[] nums)
{
return Helper(0);
// 内嵌方法(C# 7+)
int Helper(int i)
{
if (i >= nums.Length) return 0;
return nums[i] + Helper(i + 1);
}
}
写递归 / 闭包 / 不希望污染类作用域时方便。
异步方法
public async Task<string> FetchAsync(string url)
{
using var client = new HttpClient();
return await client.GetStringAsync(url);
}
// 调用
string html = await FetchAsync("https://example.com");
详见 第 16 篇。
扩展方法
public static class StringExtensions
{
// 第一个参数前加 this
public static int CountVowels(this string s)
{
return s.Count(c => "aeiouAEIOU".Contains(c));
}
}
// 用:像 string 自己的方法
"hello".CountVowels(); // 2
整个 LINQ 都是基于这个机制——IEnumerable<T>.Where 实际上是扩展方法。
返回多值
用 tuple
public (int min, int max) MinMax(int[] arr)
{
return (arr.Min(), arr.Max());
}
var (lo, hi) = MinMax(new[] { 3, 1, 4, 1, 5 });
Console.WriteLine($"{lo}, {hi}");
用 out
public bool TryParse(string s, out int result)
{
return int.TryParse(s, out result);
}
if (TryParse("123", out var n))
{
Console.WriteLine(n);
}
out 在标准库(TryGetValue / TryParse)大量使用。
局部静态函数(C# 8+)
public int Compute()
{
int outer = 10;
return Helper(5);
static int Helper(int x) => x * 2; // 不能访问 outer
}
static 局部函数禁止闭包——明确"不依赖外部状态",编译器能更好优化。
→ 下一篇 类与属性