====== 函数与方法 (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);