c#ref、out和in关键字

c#ref、out和in关键字

ref和out关键字,还有一个in关键字

这三个关键字都是用来修饰参数的,并且如果方法中使用了相应的关键字,在调用方法的时候,也必须加上使用的关键字。

ref关键字的作用

  • 在c#中,函数中的参数如果按照值类型的方式去传递,则在该函数执行完毕后,不会改变原来的实际参数的值。

  • ref和out关键字的作用就是,如果参数按照值类型的方式去传递,则在函数执行完毕后,会改变原来的实参。

    如下列代码

    int a = 20;//一个值类型的变量
    public void Number(int aa)//aa是形参
    {
    aa = 50;
    }
    Number(a);//将实参a传入到方法Number中去
    Console.WriteLine(a);
    输出的结果 是 20,而不是50,//因为a是值类型,虽然方法内形参aa赋值50,但是他只方法结束后,a的值不会被形参改变。在值类型传递的时候,会对参数进行复制,在函数内部操作的那个实际上是复制品,所有它不会改变本尊的值。  
    
使用ref关键字
int a = 20;
public void Number(ref int aa)
{
    aa = 50;
}
Number(ref a)//调用的时候要加上ref
Console.WriteLine(a);
输出的结果是50,而不是20。//因为使用了ref关键字,虽然是值类型的传递,但是ref关键字会将a的地址传递给aa,所以方法内部对aa的赋值实际上就是对a的赋值。  

out关键字的作用

  • out关键字在效果上是和ref关键字是一模一样的
int a;
public void Number(out int aa)//aa是形参
{
aa = 50;
}
Number(out a);//将实参a传入到方法Number中去
Console.WriteLine(a);

ref和out关键字的区别

  • 由上诉可知,ref和out关键字都效果是一模一样的没有任何区别,但是!!!,二者在原理和用法是不同的!!!
    • 用法上:
ref关键字修饰的变量,1.必须是已经赋值过的,2.但是可以不用在函数内部再次赋值,可以直接使用。
    如 int a =20;
    public void Number(ref int aa)
   {
    Console.Writeline(aa);
   }
out关键字修饰的变量,1.不需要提前进行赋值,2.但是必须在使用的函数内部进行赋值
    如 int a;   //声明了变量a,但是没有赋值
    public void Number(out int aa)//aa是形参
   {
    aa = 50;   ------必须在函数内部赋值,
   }
  • 通过两者在使用上的区别,可以推出,虽然二者效果是一样的,其中也都是通过地址传递来完成改变值类型在进行参数传递的时候的传递结果。但是这个传递过程是不一样的。
    • ref关键字:它是将事先定义好的变量的地址传递给函数内部的形参,这也就是为射么ref关键字在使用的时候,需要现在外部(函数的外部)进行赋值,这个赋值其实就是给他一个内存空间,让它有一个内存地址,然后使用ref关键字的时候,会将实参的内存地址传递给形参使用,所有它俩操作的是同一个内存地址,也就是同一个a。
    • out关键字:首先,如果仅仅是 int a;而不去赋值,则这个a不会占用一个内存空间,更不会有一个实际的内存地址,而out关键字修饰的形参必须在函数内部赋值的作用就是给这个形参一个内存地址,然后将这个内存地址传递给这个实参,使它们对应的也是同一个内存地址,也就是同一个a。

所以这就是为什么ref修饰的参数,必须在外部赋值过,而out修饰的参数,必须在内部赋值过,即使out修饰的参数已经在外部赋值,也必须在内部再次赋值才行。这也就是二者的唯一区别。

  • 补充:方法的重载不能通过这两个关键字去区分,如代码块1,但是可以区别一个带ref或者out的,与一个不带ref或者out的如代码2,in关键字也是一样的,没有列出来。

    • 代码1
      class CS0663_Example
      {
          // Compiler error CS0663: "Cannot define overloaded
          // methods that differ only on ref and out".
          public void SampleMethod(out int i) { }
          public void SampleMethod(ref int i) { }
      }
      
    • 代码2
      class RefOverloadExample
      {
          public void SampleMethod(int i) { }
          public void SampleMethod(ref int i) { }
      }
      

In关键字

  • 它和out和ref关键字的作用是一样的,都是将参数按照引用来传递,区别就是调用In关键字的方法,无法改变其值。如

    int readonlyArgument = 44;
    
    
    void InArgExample(in int number)
    {
         Uncomment the following line to see error CS8331
        number = 19;//此处是错误的!!!,无法在函数内部改变In关键字修饰的参数值
    }
    

以上均是个人理解,发出来就是希望有错误的地方能得到指正,万分感谢!!!

上一篇:1029:计算浮点数相除的余


下一篇:js设计模式之代理模式