什么时候会需要使用ref和out
- 有时,我们会需要获取某个值在方法中的运行状态,根据定义的方法,我们仅仅能够获得一个返回值,但是,有时我们也许想获取多个值,通过返回值就不能返回这样的信息,我们可以通过在参数前使用ref或out,以得到多个返回值.
- 在执行Sql存储过程时,我们可以通过sql语句在存储过程中的运行状态,返回相应的值.sql的return只支持Int格式的返回值,通过使用ref或out我们就可以获取多个返回值,并提示给页面
ref和out有什么区别:
当方法中的代码运行时,需要用到该参数,并且通过该参数返回所需要的值时,我们就需要使用ref.
如果仅仅是为了获取多个返回值,而方法中又不需要使用这些参数时,我们可以使用out.
示例
例1:在asp.net页面使用ref和out
protected void Page_Load(object sender, EventArgs e) { string str1, str2, s1 = "第一个参数", s2 = "第二个参数"; //运行下面一行代码,会提示以下错误: // 使用了未赋值的局部变量“str1” //UseRef(ref str1, ref str2); //输出结果: // 使用out的第一个参数 // 使用out的第二个参数 UseOut(out str1, out str2); Response.Write(str1 + "<br/>"); Response.Write(str2 + "<br/>"); //输出结果: // 第一个参数使用ref // 第二个参数使用ref UseRef(ref s1, ref s2); Response.Write(s1 + "<br/>"); Response.Write(s2 + "<br/>"); } public void UseOut(out string str1, out string str2) { str1 = "使用out的第一个参数"; str2 = "使用out的第二个参数"; } public void UseRef(ref string s1, ref string s2) { s1 += "使用ref"; s2 += "使用ref"; }例2:在存储过程中的参数使用output关键字时,对应到c#代码中,则是ref和out.
ref和out与output关系如下:
ParameterDirection取值 描述 对应C# 对应SQL Input 输入 InputOutput 输入输出 ref 对应output Output 输出 out ReturnValue 返回值 开始例子:
建立Employee表:
表内数据如下:
建立存储过程如下:
ALTER PROCEDURE dbo.InsertEmployee ( @EmployeeName nvarchar(20), @EmployeeAge int=null, @EmployeeDepartmentID int=null, @EmployeeScore int=null, @outValue nvarchar(20) output ) AS /* SET NOCOUNT ON */ if exists(select * from Employee where EmployeeName=@EmployeeName) begin set @outValue='用户名'+@EmployeeName+'重复!' return end insert into Employee (EmployeeName,EmployeeAge,EmployeeDeparmentID,EmployeeScore) values (@EmployeeName,@EmployeeAge,@EmployeeDepartmentID,@EmployeeScore) set @outValue='用户'+@EmployeeName+'建立成功!' return
页面代码如下:
string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; SqlConnection conn = new SqlConnection(connectionString); SqlCommand cmd = conn.CreateCommand(); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "InsertEmployee"; cmd.Parameters.AddWithValue("@EmployeeName", "宋八"); cmd.Parameters.AddWithValue("@EmployeeAge", 20); cmd.Parameters.AddWithValue("@EmployeeDepartmentID", 1); cmd.Parameters.AddWithValue("@EmployeeScore", 95); //注意param_outValue.Direction // 设置param_outValue.Direction=Output,参数只需被声明即可 // 对应数据库中output //SqlParameter param_outValue = new SqlParameter("@outValue", SqlDbType.NVarChar, 20); //param_outValue.Direction = ParameterDirection.Output; //cmd.Parameters.Add(param_outValue); //注意param_outValue.Direction // 设置为param_outValue.Direction=InputOutput,参数需要被初始化 // 对应数据库中output SqlParameter param_outValue = new SqlParameter("@outValue", SqlDbType.NVarChar,20); param_outValue.Direction = ParameterDirection.InputOutput; param_outValue.Value = string.Empty; cmd.Parameters.Add(param_outValue); conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); Response.Write(param_outValue.Value);
第一次运行输出结果:
用户宋八建立成功!
第二次运行输出结果:
用户名宋八重复!