====== 函数与方法 (Functions & Methods) ====== 本章节详细讲解 C# 中函数的定义、参数传递机制、构造函数、系统常用函数以及高级用法(如委托和递归)。 ===== 基础概念 ===== ==== 形参与实参 ==== * **形参 (Formal Parameter)**: 在定义一个函数时,用于接收数据的占位符变量。 * **实参 (Actual Parameter)**: 在调用一个函数时,实际传入的具体数值或变量。 ===== 函数的高级特性 ===== ==== 1. 函数的重载 (Method Overloading) ==== 方法重载是指在同一个类中定义多个**同名**但**参数列表不同**(参数数量、类型或顺序不同)的方法。 class Tise { // 重载1:处理 int public int Add(int a, int b) { return a + b; } // 重载2:处理 double public double Add(double a, double b) { return a + b; } // 重载3:处理 string public string Add(string a, string b) { return a + b; } } ==== 2. 函数的递归 (Recursion) ==== **定义**: 方法自己调用自己。 **注意**: 必须有一个明确的**停止条件**,否则会导致栈溢出。 class Program { public static int i = 0; // 定义静态字段用于计数 static void Main(string[] args) { Fang_1(i); Console.ReadKey(); } public static void Fang_1(int i) { Console.WriteLine("已调用次数:" + i.ToString()); // 停止条件 if (i >= 10) { return; // 退出方法 } i++; Fang_1(i); // 递归调用 } } ===== 高级参数修饰符 ===== ==== 1. out 参数 (输出参数) ==== **特点**: * 侧重于从函数内返回多个不同类型的值。 * 传入前无需初始化。 * **必须**在方法内部赋值。 static void Main(string[] args) { int[] num = new int[] { 2, 3, 5, 5 }; // 定义变量接收返回值 int int_data; double double_data; string string_data; // 调用函数 tise_out(num, out int_data, out double_data, out string_data); } /// /// out参数返回多个值 /// public static void tise_out(int[] nums, out int num1, out double num2, out string Str) { // out 参数在函数内部一定要赋值 num1 = nums[0] * nums[1]; num2 = (double)nums[0] / nums[1]; Str = "ID=5364"; } ==== 2. ref 参数 (引用参数) ==== **特点**: * 将变量带入函数中,改变后,再将其值带回。 * 相当于把参数既当输入又当输出 (In/Out)。 * 传入前**必须**初始化。 // 案例:交换两个数的值 static void Main(string[] args) { int num1 = 5, num2 = 2; Woid(ref num1, ref num2); // 此时 num1=2, num2=5 } public static void Woid(ref int num1, ref int num2) { int a = num1; num1 = num2; num2 = a; } ==== 3. params 参数 (可变参数) ==== **特点**: * 允许传入任意数量的同类型参数。 * 编译器会自动将其封装为数组。 * 必须是参数列表的最后一个参数。 static void Main(string[] args) { int Add_Data; // 可以传入不同数量的参数 test(out Add_Data, 50, 36, 52, 25); test(out Add_Data, 50, 36, 52, 25, 59); Console.WriteLine("结果=" + Add_Data.ToString()); } public static void test(out int add, params int[] num) { // 返回第一个与最后一个的和 if (num.Length > 0) add = num[0] + num[num.Length - 1]; else add = 0; } ===== 构造函数 (Constructor) ===== **定义**: 在创建类对象(new)时自动调用的特殊方法,用于初始化对象。 **特点**: 方法名与类名相同,无返回值类型。 public class MyClass { // 1. 无参构造函数 public MyClass() { Console.WriteLine("无参构造函数被调用"); } // 2. 带参数的构造函数 (重载) public MyClass(int x) { Console.WriteLine("带参数被调用:" + x); } } // 使用 MyClass obj1 = new MyClass(); // 调用无参 MyClass obj2 = new MyClass(42); // 调用有参 ===== 50-4:常用系统函数 ===== ==== 1. MessageBox (消息弹窗) ==== WinForms 中常用的交互弹窗。 // 基础用法 MessageBox.Show("内容"); // 带标题、按钮、图标 MessageBox.Show("登录成功!", "消息提醒", MessageBoxButtons.YesNo, MessageBoxIcon.Question); // 图标选项: Question(?), Warning(!), Stop(X), Exclamation(i) // 接收返回值 (判断用户点了哪个按钮) DialogResult renu = MessageBox.Show("确定删除吗?", "提醒", MessageBoxButtons.YesNo); if (renu == DialogResult.Yes) { // 用户点了 Yes } else { // 用户点了 No } ==== 2. Stopwatch (程序计时器) ==== 用于测量代码运行时间,位于 `System.Diagnostics` 命名空间。 using System.Diagnostics; Stopwatch sw = new Stopwatch(); // 创建对象 sw.Start(); // 开始计时 // ... 运行的代码 ... sw.Stop(); // 停止计时 string time = sw.Elapsed.ToString(); // 获取经过的时间 ==== 3. Random (随机数) ==== Random r = new Random(); // 实例化 int SuiJiShu = r.Next(1, 4); // 产生 1 到 3 的随机数 (左闭右开区间) ===== 50-5:实用算法与自定义函数案例 ===== ==== 1. 闰年计算与日期处理 ==== void 计算闰年函数(int Yue) { int day = 0; switch (Yue) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: day = 31; break; case 2: // 闰年公式:能被400整除 OR (能被4整除 AND 不能被100整除) if ((Yue % 400 == 0) || (Yue % 4 == 0 && Yue % 100 != 0)) day = 29; else day = 28; break; default: day = 30; break; } } ==== 2. 数据高低位拆解 ==== 常用于工业通讯协议处理。 // 获取高8位 byte shujiCaiJie_GaoWei(uint num1) { return (byte)(num1 >> 8); } // 获取低8位 byte shujiCaiJie_DiWei(uint num1) { return (byte)num1; } ==== 3. 查找最大/最小值 ==== static int GetMax(List nums) { int max = nums[0]; foreach (var num in nums) { if (num > max) max = num; } return max; } ==== 4. 文件操作 (1秒创建一个文件) ==== // 核心逻辑:利用当前时间作为文件名 string Now_time = DateTime.Now.ToString(); string file_Name = Now_time.Replace("/", "_").Replace(":", ".") + ".txt"; FileInfo file1 = new FileInfo("D:\\Path\\" + file_Name); if (!file1.Exists) { file1.Create(); } ==== 5. 栈 (Stack) 的简易模拟 ==== class Zhan { private int[] zhan_Cpu = new int[300]; // 入栈 public void Set(int valu, int index) { zhan_Cpu[index] = valu; } // 出栈 public int Get(int index) { return zhan_Cpu[index]; } } ===== 函数使用技巧与委托 ===== ==== 1. 方法调用规则 ==== * **静态方法 (static)**: 可以直接调用其他静态方法;不能直接调用非静态方法(需实例化)。 * **动态方法**: 可以调用静态方法,也可以调用动态方法。 ==== 2. 委托 (Delegate) - 将函数作为参数传递 ==== 委托可以看作是函数的指针或容器。 **方式 A: 使用 Action/Func (系统内置委托)** public class Program { public static void Main() { // 将 Add 和 Display 函数作为参数传入 ExecuteFunction ExecuteFunction(Add, Display, 3, 5); } public static int Add(int a, int b) => a + b; public static void Display(int result) => Console.WriteLine("Result: " + result); // Func<参数1, 参数2, 返回值> // Action<参数> (无返回值) public static void ExecuteFunction(Func function, Action displayFunction, int a, int b) { int result = function(a, b); // 执行传入的加法函数 displayFunction(result); // 执行传入的显示函数 } } **方式 B: 自定义 Delegate** // 1. 定义委托签名 public delegate int MyDelegate(int a, int b); public class ClassB { // 2. 方法接收委托作为参数 public void Process(MyDelegate del, int a, int b) { int result = del(a, b); // 执行委托 Console.WriteLine("Result: " + result); } } // 调用 ClassA a = new ClassA(); ClassB b = new ClassB(); // 将 a.Add 方法包装成委托传入 b.Process b.Process(new MyDelegate(a.Add), 5, 3);