目录
out关键字:
通常一个方法只能返回一个值,但是如果在某些时候,我们想要返回多个值,例如某个方法将一个浮点数分割成一个整数和一个小数返回去。这个时候我们就要用到out关键字。
如果用ref也可以解决,但是用ref需要在初始化的时候虚设一个值,并且还要给虚设值赋初始值。
using System;
namespace ConsoleApp7
{
class Program
{
static void Main(string[] args)
{
double f;
int i = TestOut.GetParts(2.55f, out f);
Console.WriteLine("整数部分:" + i);
Console.WriteLine("小数部分:" + f);
Console.WriteLine("小数部分:{0:#.###}", f);
Console.ReadKey();
}
}
class TestOut
{
public static int GetParts(double n,out double frac)
{
int whole = (int)n;
frac = n - whole;
return whole;
}
}
}
ref关键字:
using System;
namespace ConsoleApp8
{
class Program
{
static void Main(string[] args)
{
int a = 1;
int b = 2;
Console.WriteLine("交换前:a={0},b={1}", a, b);
Swap(a,b);
Console.WriteLine("交换后:a={0},b={1}", a, b);
Console.ReadKey();
}
public static void Swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
Console.WriteLine("交换时:a={0},b={1}", a, b);
}
}
}
我们发现交换失败!
原因分析:int类型为值类型,它存在于线程的堆栈中。当调用Swap(a,b)方法时,相当于把a,b的值(即1,2)拷贝一份,然后在方法内交换这两个值。交换完后,a还是原来的a,b还是原来的b。这就是C#中按值传递的原理,传递的是变量所对应数据的一个拷贝,而非引用。ref和out关键字将告诉编译器,现在传递的是参数的地址而不是参数本身
using System;
namespace ConsoleApp8
{
class Program
{
static void Main(string[] args)
{
int a = 1;
int b = 2;
Console.WriteLine("交换前:a={0},b={1}", a, b);
Swap(ref a,ref b);
Console.WriteLine("交换后:a={0},b={1}", a, b);
Console.ReadKey();
}
public static void Swap(ref int a,ref int b)
{
int temp = a;
a = b;
b = temp;
Console.WriteLine("交换时:a={0},b={1}", a, b);
}
}
}
总结:
C#中的ref和out提供了值类型按引用进行传递的解决方案,当然引用类型也可以用ref和out修饰,但这样已经失去了意义。因为引用数据类型本来就是传递的引用本身而非值的拷贝。ref和out关键字将告诉编译器,现在传递的是参数的地址而不是参数本身,这和引用类型默认的传递方式是一样的。