//如下
方法参数上的 out 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
当希望方法返回多个值时,声明 out 方法非常有用。使用 out 参数的方法仍然可以返回一个值。一个方法可以有一个以上的 out 参数。
若要使用 out 参数,必须将参数作为 out 参数显式传递到方法。out 参数的值不会传递到 out 参数。
不必初始化作为 out 参数传递的变量。然而,必须在方法返回之前为 out 参数赋值。
属性不是变量,不能作为 out 参数传递。
方法参数上的 ref 方法参数关键字使方法引用传递到方法的同一个变量。当控制传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。
若要使用 ref 参数,必须将参数作为 ref 参数显式传递到方法。ref 参数的值被传递到 ref 参数。
传递到 ref 参数的参数必须最先初始化。将此方法与 out 参数相比,后者的参数在传递到 out 参数之前不必显式初始化。
属性不是变量,不能作为 ref 参数传递。
//上面的理解起来非常不好理解。下面的理解起来容易一些。
首先:两者都是按地址传递的,使用后都将改变原来的数值。很多人在论坛上解释说out是按数值传递,是错误的。简单的测试后可以知道out使用也能改变数值的,所以肯定是按照地址传递的。其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。这个就是两个的区别,或者说就像有的网友说的,ref是有进有出,out是只出不进。经典!!!
自己做了一个小小的测试。
客户端代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="reforout.aspx.cs" Inherits="reforout" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>ref与out的区别的示例</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnRef" runat="server" Text="参数Ref" OnClick="btnRef_Click" />
<asp:Button ID="btnOut" runat="server" Text="参数Out" OnClick="btnOut_Click" />
</div>
</form>
</body>
</html>
服务端代码:
using System;
public partial class reforout : System.Web.UI.Page
{
/// <summary>
/// 调用参数为ref的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnRef_Click(object sender, EventArgs e)
{
int number = 10;
RefExampleMethod(ref number);
Response.Write("number = "+number);
}
/// <summary>
/// 调用out参数的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnOut_Click(object sender, EventArgs e)
{
int number = 20;
string str= OutExampleMethod(out number);
Response.Write(str +":"+number);
}
/// <summary>
/// ref参数
/// </summary>
/// <param name="num"></param>
/// <returns></returns>
private bool RefExampleMethod(ref int num)
{
//ref有进有出
if (num > 5)
num = 15;
else
num = 1;
return true;
}
private string OutExampleMethod(out int num)
{
//注释处不可用用num判断,否则编译不通过,因为out传入的值,out是只出不进
//if (num > 10)
// num = 10;
//else
num = 5;
return "哈哈,这是out参数";
}
}
总结:1)当调用方法前,必须给ref的参数初始化,out的参数可以初始化,也可以不用初始化
2)在调用的方法中,必须重新给out初始化值(也就是和out传进来的初始化值无关)
public int PrintNumber(out int num)
{
num+=2;//会报错
必须先给num赋值,再返回
return num;//会报错
num=3;
return num;//正确
}
所谓的“只出不进”就是无论给out传入了什么值,在调用的方法中,都会被初始化(即与传入的值无关)