c#中关键字ref与out的区别

一、关键字ref的使用:

  • 参数为简单类型的例子
static void Main(string[] args)
        {
            string temp = "a";
            Change(temp);
            Console.WriteLine(temp);


            ChangeByRef(ref temp);
            Console.WriteLine(temp);
            Console.ReadKey();
        }


        private static void Change(string temp)
        {
            temp = temp + "--changed";
        }


        private static void ChangeByRef(ref string temp)
        {
            temp = temp + "--refchanged";
        }
输出结果:
a
a--refchanged

● 在Change()方法中,虽然改变了temp的值,但方法没有返回值,输出temp依然是初始值a;

● 在ChnageByRef()方法中,由于加上了关键字,虽然也没有返回值,当改变temp的值后,temp的引用地址发生了改变,再次输出, temp的值为新的引用地址对应的值。

  • 参数是类类型的例子
class Program
    {
        static void Main(string[] args)
        {
            Pet p = new Pet(){Age = 5};
            Console.WriteLine("初始年龄是:{0}", p.Age);
            ChangeAge(p);
            Console.WriteLine("改变pet的属性值后,年龄是:{0}", p.Age);
            ChangeAgeByRef(ref  p);
            Console.WriteLine("改变pet引用地址后,年龄是:{0}", p.Age);
            Console.ReadKey();
        }


        private static void ChangeAge(Pet p)
        {
            p.Age = 10;
        }


        private static void ChangeAgeByRef(ref Pet p)
        {
            p = new Pet(){Age = 20};
        }
    }


    public class Pet
    {
        public int Age { get; set; }
    }
输出结果:
初始年龄是:5
改变pet的属性值后,年龄是:10
改变pet引用地址后,年龄是:20

● 在ChangeAge()方法中,改变的是Pet实例的属性值。
● 在ChangeAgeByRef()方法中,改变的Pet实例的引用地址。


总结:方法参数无论是简单类型,还是类类型,当在其前加上ref关键字后,对参数的赋值,实际上是改变的是方

法参数变量的引用地址。使用ref注意点:

● 使用带ref的方法之前,需要给方法参变量赋上初始值

● 无论是定义方法还是使用方法,都要带上关键字ref


二、关键字ref与out的区别

1.两者都是按地址传递的,使用后都将改变原来参数的数值。ref是传递参数的地址,out是返回值。
2.使用ref前必须对变量赋值,out不用;进入out的函数时会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,ref引用的可以修改,也可以不修改。


例子
using System; 
 class TestApp 
 { 
 static void outTest(out int x, out int y) 
 {//离开这个函数前,必须对x和y赋值,否则会报错。 
 //y = x; 
 //上面这行会报错,因为使用了out后,x和y都清空了,需要重新赋值,即使调用函数前赋过值也不行 
 x = 1; 
 y = 2; 
 } 
 static void refTest(ref int x, ref int y) 
 { 
 x = 1; 
 y = x; 
 } 
 public static void Main() 
 { 
 //out test 
 int a,b; 
 //out使用前,变量可以不赋值 
 outTest(out a, out b); 
 Console.WriteLine("a={0};b={1}",a,b); 
 int c=11,d=22; 
 outTest(out c, out d); 
 Console.WriteLine("c={0};d={1}",c,d); 
 //ref test 
 int m,n; 
 //refTest(ref m, ref n); 
 //上面这行会出错,ref使用前,变量必须赋值 
 int o=11,p=22; 
 refTest(ref o, ref p); 
 Console.WriteLine("o={0};p={1}",o,p); 
 } 
 }
输出结果:
a=1;b=2
c=1;d=2

o=1;p=1


总结:ref和out的区别在C# 中,既可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数,可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量。它们的区别是:

1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化, 必须方法返回之前为 out 参数赋值。

2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。

3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。


注: 在C#中,方法的参数传递有四种类型:传值(by value),传址(by reference),输出参数(by output),数组参数(by array)。传值参数无需额外的修饰符,传址参数需要修饰符ref,输出参数需要修饰符out,数组参数需要修饰符params。传值参数在方法调用过程中如果改变了参数的值,那么传入方法的参数在方法调用完成以后并不因此而改变,而是保留原来传入时的值。传址参数恰恰相反,如果方法调用过程改变了参数的值,那么传入方法的参数在调用完成以后也随之改变。实际上从名称上我们可以清楚地看出两者的含义--传值参数传递的是调用参数的一份拷贝,而传址参数传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。






 
















 










 




 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值