函数参数默认是值传递的,也就是“复制一份”,通过函数的处理对数值本身并没有影响,如果函数想对数值本身产生影响就需要使用相应的参数。
ref必须先初始化,因为是引用,所以必须先“有”,才能引用。使用ref如果未进行初始化,将报出如图所示的错误使用了未赋值的局部变量“age”:
加上ref之后传参传的是引用而不再是没加ref时的拷贝。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace refout参数
{
class Program
{
static void Main(string[] args)
{
int age;
IncAge(ref age);
Console.WriteLine(age);
Console.ReadKey();
}
static void IncAge(ref int age)
{
age++;
}
}
}
out是内部为外部赋值,所以不需要初始化,而且初始化也没用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace refout参数
{
class Program
{
static void Main(string[] args)
{
int age;
IncAge(out age);
Console.WriteLine(age);
Console.ReadKey();
}
static void IncAge(out int age)
{
age=20;
}
}
}
执行结果:
总结:ref应用场景内部对外部的值进行改变,out则是内部为外部变量赋值,out一般用在函数有多个返回值的场所。
out应用举例:int.TryParse
int.Parse()是一种类容转换;表示将数字内容的字符串转为int类型。
如果字符串为空,则抛出ArgumentNullException异常;
如果字符串内容不是数字,则抛出FormatException异常;
如果字符串内容所表示数字超出int类型可表示的范围,则抛出OverflowException异常;
int.TryParse 与 int.Parse 又较为类似,但它不会产生异常,转换成功返回 true,转换失败返回 false。最后一个参数为输出值,如果转换失败,输出值为 0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace refout参数
{
class Program
{
static void Main(string[] args)
{
string str = Console.ReadLine();
int i;
if (int.TryParse(str ,out i)) //i在内部被赋值
{
Console.WriteLine("转换成功!{0}",i);
}
else
{
Console.WriteLine("转换失败!{0}",i);
}
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace refout参数
{
class Program
{
static void Main(string[] args)
{
int i1 = 10;
int i2 = 20;
Swap(ref i1,ref i2); //注意ref参数
Console.WriteLine("i1={0},i2={1}", i1, i2);
Console.ReadKey();
}
static void Swap(ref int i1,ref int i2) //注意ref参数
{
int temp = i1;
i1 = i2;
i2 = temp;
}
}
}