01、 本文背景
原本我是一个地地道道的C/C++开发者,我其实很难想象有一天我会去接触其他语言,因为当初我就是奔着C/C++学完可以打天下,此意并不是说我不想学习,只是不想接触更多的语言,我认为知识的深度比广度更值得付出时间。
言归正传!
入职之后,一年都是用C++编程、但是最近,公司交给我了一个新任务,接触一个新的项目,这个项目的源代码是其他公司的,只不过被我们的客户买来做二次开发,然后我们公司的板卡最后肯定是要替换掉现在的项目内板卡,所以,研究此项目,搞懂此项目就迫在眉睫。没错,这个项目是一个纯C#项目,我虽然学过两天但是,有一说一,只是了解一些语法,写游戏项目的时候用C#写过几行脚本。
在查看项目源码的过程中,就被ref 与 out 这两个关键字搞得有点不明不白,最后查询资料之后,搞懂了所谓的ref与out,这里总结一下,算是给自己花费的时间做一个总结叭!
02、ref的定义与使用
ref的定义:
ref:MSDN的定义为:“The ref keyword indicates a value that is passed by reference.”就是通过引用来传递参数。ref也是Reference的缩写。了解了定义之后,ref怎么用呢?首先我们要明白值类型和引用类型的概念。这里的ref基本上就是服务于值类型的。
ref的使用:
public static void VerifyRefInt(int buffer)
{//不带ref
buffer += 520;
}
public static void VerifyRefDouble(ref double buffer)
{//带ref
buffer += 520.0;
}
static void Main(string[] args)
{
int a = 1;
double b = 1.0;
VerifyRefInt(a);
VerifyRefDouble(ref b); //调用的时候ref也不能忘记,不然会报错
Console.WriteLine("VerifyRefInt output Result: {0}",a);
Console.WriteLine("VerifyRefDouble output Result: {0:f1}",b);
Console.ReadKey();
//Console.ReadLine(); //以上两句都是同样的作用:阻塞,使黑色框框暂停,让我们看得见runing result。
}
runing result:
从结果不难看出:
- 不使用ref的时候,buffer外部传入1,VerifyRefInt算出来肯定是521,但是函数块执行完毕之后输出结果时,里面的内容已经被销毁,局部变量(与C++性质一样,这里不重复),所以结果还是1。
- 使用ref的时候,buffer外部传入1.0,VerifyRefDouble算出来肯定是521.0,由于加了ref关键字,表示使用的引用传递,类似C++的指针与引用(地址传递),修改的是地址的内容,所以,输出地址里面的值,变为了521.0。
03、out的定义与使用
out的定义:(MSDN摘录)
- 第一部分
As a parameter modifier, which lets you pass an argument to a method by reference rather than by value./“out”作为一个参数修饰符,允许您通过引用而不是通过值将参数传递给方法。
- 第二部分
In generic type parameter declarations for interfaces and delegates, which specifies that a type parameter is covariant./在接口和委托的泛型类型参数声明中,它指定类型参数是协变的。
今天的语境下,我们只讨论第一种作为引用传递参数的定义。
委托的泛型类型参数声明暂时我还没发说的很清楚,后面C#用多了,了解其意义了再提出来
out的使用:
public static void VerifyOutOne(int buffer)
{//不带out
buffer = 555;
}
public static void VerifyOutTwo(out int buffer)
{//带out
buffer = 1024;
}
static void Main(string[] args)
{
int a;
int b;
VerifyOutOne(a);
VerifyOutTwo(out b);
Console.Write("VerifyOutOne output resutl: {0}",a);
Console.Write("VerifyOutTwo output result: {0}",b);
Console.ReadLine();
}
runing result:
从运行结果不难看出:不带out的,外部定义为0,调用改值函数之后,结果还是0。带out的,外部没有赋值也能调用(区别),然后运行结果是1024,说明out可以变量不赋值,然后效果与ref类似。
04、ref与out的区别
Stack Overflow的解释:
意思就是:当你在使用ref传递参数的时候,ref修饰的参数必须要有值,但是out可以使用一个未赋值的变量作为参数传递。下面我也用代码做了验证。
class RefAndOut
{
public static void OutDouble(out int outInt)
{
outInt = 2;
Console.WriteLine("outInt is:"+outInt);
}
public static void RefDouble(ref int parInt)
{
parInt *= 2;
Console.WriteLine("refInt is:"+parInt);
Console.ReadKey();
}
public static void NormalDouble(int IntPar)
{
IntPar = 1;
IntPar *= 2;
Console.WriteLine("normalInt is:" + IntPar);
Console.ReadKey();
}
static void Main(string[] args)
{
int refInt;
int outInt;
int normalInt;
OutDouble(out outInt);
RefDouble(ref refInt);
NormalDouble(normalInt);
}
}
这段代码在两处地方有错误:即在使用ref,和不使用修饰符的时候,必须要传递一个有值的参数。所以你看,ref和out几乎就只有一个区别,那就是out可以使用未赋值的变量。
05、小结
上诉内容通过自己代码敲出来验证过了,也许不能说得面面俱到,但是我尽量说得清晰、易懂。我也是刚开始接触C#,以后还希望在csdn跟大家一起学习,有问题大家也可以和我一起交流!
QQ:1012569730
VX:Cain_Xcy233
有问题还希望大家指出来,一起进步,谢谢!
版权声明:转载请注明出处,谢谢!