跳至内容
张叶安的小站
用户工具
登录
站点工具
搜索
工具
显示页面
过去修订
反向链接
最近更改
媒体管理器
网站地图
登录
>
最近更改
媒体管理器
网站地图
您的足迹:
csharp:第三章方法
本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。
====== 第三章 方法 ====== ===== 3.1 方法基础 ===== === 什么是方法 === 方法(Method)是执行特定任务的代码块,是组织和重用代码的基本单元。通过方法,我们可以将复杂的程序分解为可管理的小块。 === 方法的基本结构 === <code csharp> [访问修饰符] [返回类型] 方法名([参数列表]) { // 方法体 // 执行语句 [return 返回值;] } </code> === 方法定义示例 === <code csharp> // 无参数无返回值 void SayHello() { Console.WriteLine("Hello, World!"); } // 有参数无返回值 void Greet(string name) { Console.WriteLine($"Hello, {name}!"); } // 有参数有返回值 int Add(int a, int b) { return a + b; } // 无参数有返回值 string GetCurrentTime() { return DateTime.Now.ToString("HH:mm:ss"); } </code> ===== 3.2 参数传递 ===== === 值传递 === 默认情况下,C#使用值传递。方法接收的是参数的副本,修改不影响原始值。 <code csharp> void Increment(int number) { number++; // 只修改副本 Console.WriteLine($"方法内部: {number}"); } int value = 10; Increment(value); Console.WriteLine($"方法外部: {value}"); // 仍然是10 </code> === 引用传递(ref) === 使用ref关键字,方法可以修改原始变量的值。 <code csharp> void IncrementByRef(ref int number) { number++; // 修改原始值 } int value = 10; IncrementByRef(ref value); Console.WriteLine(value); // 输出11 </code> === 输出参数(out) === out参数用于从方法返回多个值,调用前不需要初始化。 <code csharp> void Calculate(int a, int b, out int sum, out int difference) { sum = a + b; difference = a - b; } int s, d; Calculate(10, 5, out s, out d); Console.WriteLine($"和: {s}, 差: {d}"); // 丢弃不需要的输出 Calculate(10, 5, out int sum, out _); </code> === in参数(C# 7.2+) === in参数提供只读的引用传递,提高大型结构体的传递效率。 <code csharp> void Display(in Point point) { Console.WriteLine($"X: {point.X}, Y: {point.Y}"); // point.X = 10; // 编译错误!不能修改in参数 } struct Point { public int X { get; set; } public int Y { get; set; } } </code> === 参数数组(params) === params允许传递可变数量的参数。 <code csharp> int Sum(params int[] numbers) { int total = 0; foreach (int num in numbers) { total += num; } return total; } // 多种调用方式 Console.WriteLine(Sum(1, 2, 3)); // 6 Console.WriteLine(Sum(1, 2, 3, 4, 5)); // 15 Console.WriteLine(Sum()); // 0 Console.WriteLine(Sum(new[] { 1, 2, 3 })); // 6 </code> === 命名参数和可选参数 === <code csharp> // 可选参数(带默认值) void PrintInfo(string name, int age = 18, string city = "北京") { Console.WriteLine($"{name}, {age}岁, 来自{city}"); } // 调用 PrintInfo("张三"); // 使用默认值 PrintInfo("李四", 25); // 指定年龄 PrintInfo("王五", city: "上海"); // 使用命名参数跳过前面的参数 PrintInfo(name: "赵六", age: 30, city: "广州"); // 全部使用命名参数 </code> ===== 3.3 返回值 ===== === 单一返回值 === <code csharp> int Multiply(int a, int b) { return a * b; } string GetFullName(string firstName, string lastName) { return $"{lastName} {firstName}"; } </code> === 元组返回多个值(C# 7+) === <code csharp> // 返回元组 (int sum, int difference) Calculate(int a, int b) { return (a + b, a - b); } // 调用 var result = Calculate(10, 5); Console.WriteLine($"和: {result.sum}, 差: {result.difference}"); // 解构 (int s, int d) = Calculate(10, 5); </code> === 引用返回值(C# 7+) === <code csharp> int[] numbers = { 1, 2, 3, 4, 5 }; ref int Find(int[] arr, int target) { for (int i = 0; i < arr.Length; i++) { if (arr[i] == target) { return ref arr[i]; } } throw new InvalidOperationException("未找到"); } ref int found = ref Find(numbers, 3); found = 30; // 修改数组中的值 Console.WriteLine(string.Join(", ", numbers)); // 1, 2, 30, 4, 5 </code> ===== 3.4 方法重载 ===== === 重载规则 === 方法重载允许在同一个类中定义多个同名方法,只要它们的参数列表不同。 <code csharp> class Calculator { // 重载Add方法 public int Add(int a, int b) { return a + b; } public double Add(double a, double b) { return a + b; } public int Add(int a, int b, int c) { return a + b + c; } public string Add(string a, string b) { return a + b; } } // 使用 var calc = new Calculator(); Console.WriteLine(calc.Add(1, 2)); // 3 Console.WriteLine(calc.Add(1.5, 2.5)); // 4.0 Console.WriteLine(calc.Add(1, 2, 3)); // 6 Console.WriteLine(calc.Add("Hello, ", "World")); // "Hello, World" </code> === 重载决策 === <code csharp> class OverloadDemo { public void Method(int x) => Console.WriteLine("int"); public void Method(long x) => Console.WriteLine("long"); public void Method(double x) => Console.WriteLine("double"); public void Method(object x) => Console.WriteLine("object"); } var demo = new OverloadDemo(); demo.Method(5); // int - 精确匹配 demo.Method(5L); // long demo.Method(5.0); // double demo.Method("text"); // object </code> ===== 3.5 递归 ===== === 递归基础 === 递归是方法调用自身的编程技巧,必须包含终止条件。 <code csharp> // 阶乘计算 int Factorial(int n) { if (n <= 1) // 终止条件 return 1; return n * Factorial(n - 1); } Console.WriteLine(Factorial(5)); // 120 (5! = 5*4*3*2*1) </code> === 斐波那契数列 === <code csharp> int Fibonacci(int n) { if (n <= 1) return n; return Fibonacci(n - 1) + Fibonacci(n - 2); } // 输出前10个斐波那契数 for (int i = 0; i < 10; i++) { Console.Write(Fibonacci(i) + " "); } // 输出: 0 1 1 2 3 5 8 13 21 34 </code> === 递归 vs 迭代 === <code csharp> // 递归版本 int FactorialRecursive(int n) { if (n <= 1) return 1; return n * FactorialRecursive(n - 1); } // 迭代版本(更高效) int FactorialIterative(int n) { int result = 1; for (int i = 2; i <= n; i++) { result *= i; } return result; } </code> ===== 3.6 局部函数(C# 7+) ===== === 基本用法 === <code csharp> int CalculateFactorial(int n) { // 局部函数 int Factorial(int x) { if (x <= 1) return 1; return x * Factorial(x - 1); } if (n < 0) throw new ArgumentException("n必须非负"); return Factorial(n); } </code> === 捕获变量 === <code csharp> void OuterMethod(int factor) { // 局部函数可以访问外部方法的变量 int Multiply(int x) => x * factor; Console.WriteLine(Multiply(5)); // 5 * factor Console.WriteLine(Multiply(10)); // 10 * factor } </code> ===== 3.7 匿名方法与Lambda表达式 ===== === 匿名方法(C# 2.0) === <code csharp> // 已较少使用,主要用于兼容性 delegate void MyDelegate(string message); MyDelegate del = delegate(string msg) { Console.WriteLine(msg); }; del("Hello from anonymous method"); </code> === Lambda表达式(C# 3.0+) === <code csharp> // 表达式Lambda Func<int, int> square = x => x * x; Console.WriteLine(square(5)); // 25 // 语句Lambda Action<string> greet = name => { Console.WriteLine($"Hello, {name}!"); Console.WriteLine("Welcome!"); }; greet("Alice"); // 多参数Lambda Func<int, int, int> add = (a, b) => a + b; // 无参数Lambda Action sayHello = () => Console.WriteLine("Hello!"); </code> ===== 3.8 扩展方法 ===== === 定义扩展方法 === <code csharp> // 必须定义在静态类中 public static class StringExtensions { // 使用this关键字 public static bool IsNullOrEmpty(this string str) { return string.IsNullOrEmpty(str); } public static string Reverse(this string str) { char[] chars = str.ToCharArray(); Array.Reverse(chars); return new string(chars); } public static int WordCount(this string str) { return str.Split(new[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries).Length; } } // 使用 string text = "Hello World"; Console.WriteLine(text.Reverse()); // dlroW olleH Console.WriteLine(text.WordCount()); // 2 </code> ===== 3.9 方法实战 ===== === 数值计算工具类 === <code csharp> public static class MathUtils { // 计算数组平均值 public static double Average(params double[] numbers) { if (numbers.Length == 0) throw new ArgumentException("数组不能为空"); return numbers.Average(); } // 判断素数 public static bool IsPrime(int number) { if (number < 2) return false; if (number == 2) return true; if (number % 2 == 0) return false; for (int i = 3; i <= Math.Sqrt(number); i += 2) { if (number % i == 0) return false; } return true; } // 计算最大公约数 public static int GCD(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; } // 计算最小公倍数 public static int LCM(int a, int b) { return Math.Abs(a * b) / GCD(a, b); } } </code> === 字符串处理工具类 === <code csharp> public static class StringUtils { // 截断字符串 public static string Truncate(this string str, int maxLength, string suffix = "...") { if (string.IsNullOrEmpty(str) || str.Length <= maxLength) return str; return str.Substring(0, maxLength - suffix.Length) + suffix; } // 驼峰命名转换 public static string ToCamelCase(this string str) { if (string.IsNullOrEmpty(str)) return str; var words = str.Split(new[] { ' ', '_', '-' }, StringSplitOptions.RemoveEmptyEntries); return words[0].ToLower() + string.Concat(words.Skip(1).Select(w => char.ToUpper(w[0]) + w.Substring(1).ToLower())); } // 安全的转换为整数 public static int? ToIntOrNull(this string str) { return int.TryParse(str, out int result) ? result : (int?)null; } } </code> ===== 练习题 ===== === 基础练习 === 1. **基础方法**:编写一个方法IsEven,判断一个整数是否为偶数,返回布尔值。 2. **参数传递**:解释以下代码的输出结果,并说明原因: <code csharp> void Swap(int a, int b) { int temp = a; a = b; b = temp; } int x = 5, y = 10; Swap(x, y); Console.WriteLine($"x={x}, y={y}"); </code> 然后使用ref关键字修改方法,使交换真正生效。 3. **方法重载**:为Calculate类添加重载方法,支持加法、减法、乘法和除法运算,分别处理int和double类型。 === 进阶练习 === 4. **递归实现**:使用递归实现以下功能: - 计算1+2+3+...+n的和 - 计算x的n次幂 - 反转字符串 5. **多返回值**:编写一个方法AnalyzeNumber,接收一个整数,返回: - 是否为偶数 - 是否为素数 - 各位数字之和 使用元组返回多个值。 6. **扩展方法**:为DateTime类型添加扩展方法: - IsWeekend() - 判断是否为周末 - StartOfWeek() - 获取本周开始日期 - ToFriendlyString() - 返回友好的时间描述(如"今天"、"昨天"、"3天前"等) === 挑战练习 === 7. **表达式计算器**:实现一个简单的方法,可以解析并计算形如"1+2*3"的简单数学表达式(支持+、-、*、/和括号)。 8. **排列组合**:编写方法计算n个元素的排列数和组合数,使用递归和迭代两种实现方式。 9. **方法链式调用**:设计一个Fluent API的StringBuilder类,支持链式调用,例如: <code csharp> var result = new FluentBuilder() .Append("Hello") .AppendLine() .Append("World") .Replace("World", "C#") .ToString(); </code> ===== 本章小结 ===== 本章学习了C#方法的核心概念: - 方法的定义和调用 - 各种参数传递方式(值、ref、out、in、params) - 可选参数和命名参数 - 单一返回值和多元组返回值 - 方法重载的规则 - 递归的概念和应用 - 局部函数的使用 - Lambda表达式 - 扩展方法 掌握这些方法技巧后,你可以编写出结构清晰、可重用性高的代码。
csharp/第三章方法.txt
· 最后更改:
2026/02/03 19:45
由
127.0.0.1
页面工具
显示页面
过去修订
反向链接
回到顶部