且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

.net知识和学习方法系列(二十二)CLR-方法的参数out,ref

更新时间:2022-10-02 21:12:51

因为数值类型的分类是值类型和引用类型,所以方法的参数也有这两种类型。
值类型参数:
static void Main()
{
  int i=1;
Mehtod(i);
}
static void Method(int s)
{
  s=200;
}
如果方法的参数是值类型,调用者Main传递给被调用方法Method的是一个值类型的副本,即i的一个副本,i与方法Method中的s值相同,但一旦调用完毕两都就没有关系了。
引用类型:
static void Main()
{
  int[] arri=new int[]{1};
Method(arri);
}
static void Method(int[] arrs)
{
  Arrs[0]=200;
}
引用类型作为方法的参数时,调用者传递的是引用(与指针类似),即把arri数组的引用传给Method方法,这里只是把引用传递给方法,而非副本,这点就使在Main中的arri与在Method中的arrs引用的是同一个对象,在两个方法的任何地方使之改变都会影响另一个方法的数据的。
简单的说,值类型参数传递副本,引用类型参数传递引用。
 
接下来说说ref和out作为参数
先看一下下面的代码,
       static void F1(ref int i)
        {
            i = 100;
        }
        static void F2(out int i)
        {
            i = 100;
        }
看看这两个方法对应的IL
.method private hidebysig static void F1(int32& i) cil managed
{
 // 代码大小       6 (0x6)
 .maxstack 8
 IL_0000: nop
 IL_0001: ldarg.0
 IL_0002: ldc.i4.s   100
 IL_0004: stind.i4
 IL_0005: ret
} // end of method Program::F1
 
.method private hidebysig static void F2([out] int32& i) cil managed
{
 // 代码大小       6 (0x6)
 .maxstack 8
 IL_0000: nop
 IL_0001: ldarg.0
 IL_0002: ldc.i4.s   100
 IL_0004: stind.i4
 IL_0005: ret
} // end of method Program::F2
我们通过生成的中间语言看到,这两个方法只有一个差别就是在F2的参数中多了一个[out],方法体中是全部一样的。其实对于CLR来说,这两个关键字是没有区别的,都是能以引用类型的方式来操作参数。
为什么在C#中要区分out和ref呢?主要是因为out是输入参数,只希望它从方法内得到值返回,而ref即要把参数带到方法,也可以带出参数,就是说这只是C#编辑器的愿望,所以在C#中是区别的,但在CLR在运得exe的元数据是不区另的(因为托管理程序是两次编译)。
 
下面通过另一个方法看看ref和out
static void F1(ref int i)
        {
            i = 100;
        }
        static void F1(int i)
        {
            i = 100;
        }
上面的代码放在一个类中是能通过编译的,因为构成了重载
我们看以看一下普通方法的IL
.method private hidebysig static void F1(int32 i) cil managed
{
 // 代码大小       6 (0x6)
 .maxstack 8
 IL_0000: nop
 IL_0001: ldc.i4.s   100
 IL_0003: starg.s    i
 IL_0005: ret
} // end of method Program::F1
最明显的差别是参数普通方法是int32 i,而加ref,out的是int32& i,参数的不同使重载成为可以。但ref和out,如果参数类型个数相同的话刚形不成重载,因为它们是相同的,不充许出现相同方法(方法的签名)。
















本文转自桂素伟51CTO博客,原文链接:http://blog.51cto.com/axzxs/149957 ,如需转载请自行联系原作者