Kivy、BeeWare、PyQt5、Tauri、React-Native+Python后端——7大跨端方案实测对比,谁才是2024生产级首选?
2026/5/4 10:18:49
ref与out参数详解教程在 C# 中,ref和out是用于修改方法外部变量的关键字,它们允许方法通过参数引用直接操作调用者提供的变量。本文将详细介绍这两个关键字的用法、区别和最佳实践。
在 C# 中,参数传递默认是按值传递的:
int,double,struct):传递的是值的副本class,array,string):传递的是引用的副本(指向同一对象)ref和out允许我们以引用的方式传递任何类型的参数(包括值类型),使方法能够修改调用者提供的变量本身。
ref关键字ref用于在方法内部修改调用者传递的变量值。
voidModifyValue(refintnumber){number=100;// 修改调用者的变量}// 调用intnum=10;ModifyValue(refnum);Console.WriteLine(num);// 输出: 100ref的参数在传递给方法前必须初始化ref关键字voidSwap(refinta,refintb){inttemp=a;a=b;b=temp;}// 调用intx=5,y=10;Swap(refx,refy);Console.WriteLine($"x:{x}, y:{y}");// 输出: x: 10, y: 5out关键字out类似于ref,但有更严格的规则:
voidInitializeValue(outintnumber){number=100;// 必须赋值}// 调用intnum;// 不需要初始化InitializeValue(outnum);Console.WriteLine(num);// 输出: 100out参数前未初始化out参数赋值boolTryDivide(intdividend,intdivisor,outintresult,outintremainder){if(divisor==0){result=0;remainder=0;returnfalse;}result=dividend/divisor;remainder=dividend%divisor;returntrue;}// 调用if(TryDivide(10,3,outintres,outintrem)){Console.WriteLine($"结果:{res}, 余数:{rem}");// 输出: 结果: 3, 余数: 1}ref与out的主要区别| 特性 | ref | out |
|---|---|---|
| 调用前是否需要初始化 | 是 | 否 |
| 方法内是否必须赋值 | 否(可以读取已有值) | 是(必须在返回前赋值) |
| 主要用途 | 修改现有变量 | 返回额外值/初始化变量 |
| 语法清晰度 | 表明参数可能被修改 | 表明参数主要用于输出 |
refintFindLargest(int[]numbers){intmaxIndex=0;for(inti=1;i<numbers.Length;i++){if(numbers[i]>numbers[maxIndex])maxIndex=i;}returnrefnumbers[maxIndex];// 返回引用}// 调用int[]nums={1,5,3,9,2};refintlargest=refFindLargest(nums);largest=10;// 修改数组中的值Console.WriteLine(string.Join(", ",nums));// 输出: 1, 5, 3, 10, 2voidPrintValue(inintnumber)// in 相当于只读 ref{// number = 10; // 错误,不能修改Console.WriteLine(number);}// 调用intvalue=5;PrintValue(value);使用ref和out可以避免值类型的复制,在以下场景可能提高性能:
System.Drawing.Point)structLargeStruct{publiclongA,B,C,D,E,F,G,H;}// 使用 ref 避免复制voidProcessStruct(refLargeStructlarge){large.A*=2;// ...}ref/out参数更清晰out返回多个值:而不是创建新的类/结构体TryParse模式表示可能失败的操作out参数的行为/// <summary>/// 尝试将字符串转换为整数/// </summary>/// <param name="s">要转换的字符串</param>/// <param name="result">转换成功时包含结果</param>/// <returns>转换是否成功</returns>boolTryParse(strings,outintresult){// 实现...}ref/out关键字:voidMethod(refintx){...}intnum=5;Method(num);// 编译错误,缺少 refout参数:voidMethod(outintx){// 忘记赋值}// 编译错误,out 参数未赋值ref和out:out当需要读取传入的值时ref当不需要强制赋值时ref和out是 C# 中强大的特性,允许方法直接操作调用者的变量:
ref:用于修改现有变量,调用前必须初始化out:用于返回额外值,不需要初始化但必须在方法内赋值in)