zoukankan      html  css  js  c++  java
  • C#中使用ref和out传参的方法及区别

    引子

    之前在开发一个功能模块时,需要对数据进行一个统一的改动之后,返回对象的同时,还需要将一个状态值返回,根据这个值,再进行下一步的操作,第一个想到的方法是使用out参数修饰符,然后又查找了一下,发现可以使用ref和out都可以实现,那么这两种方法有哪些区别呢,查了一些资料之后,明白了用法,整理了一下,记录下来。

    具体使用

    ref的定义:MSDN的定义为:“The ref keyword indicates a value that is passed by reference.”就是通过引用来传递参数。ref也是Reference的缩写。了解了定义之后,ref怎么用呢?首先我们要明白值类型和引用类型的区别。这里的ref基本上就是服务于值类型的使用了。

    上代码:

    // 不使用 ref。
    void Function(int num)
    {
        num += 999;
    }
    
    var number = 1;
    Function(number);
    Console.WriteLine(number);
    **// 输出 : 1;**
    
    // 使用ref。
    void Function(ref int num)
    {
        num += 999;
    }
    
    var number = 1;
    Function(ref number);
    Console.WriteLine(number);
    
    **//输出:1000**

    看完代码就明白了:

    • 不使用ref的时候,方法接收到的变量值是1,然后在Function(int num)方法中,局部变量num做了累加之后,在方法执行完成之后就已经销毁了。number的值还是1。
    • 使用ref的时候,方法Function(ref int num)值收到的是number的地址,方法中执行的num+=999;此时相当于number+=999;直接修改了number地址的值,等于1000。

    结论:ref参数修饰符,是通过给方法传递值类型的参数,将方法内的变量改变后带出方法外。

    再看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.”在接口和委托的泛型类型参数声明中,它指定类型参数是协变的。

    上代码:

    // 不使用 out。
    void Function(int num)
    {
        num += 999;
    }
    
    var number = 1;
    Function(number);
    Console.WriteLine(number);
    **// 输出 : 1;**
        
    // 使用out。
    void Function(out int num)
    {
        num += 999;
    }
    
    var number = 1;
    Function(out number);
    Console.WriteLine(number);
    
    **//输出:1000**

    可以看出来,out和ref用法大差不差,几乎相同,out和ref其实都可以允许通过引用来传递参数。那么问题来了,既然ref 、out的作用看起来一样,为什么还定义了两个关键字呢,有何区别呢?区别就是,使用ref传递参数的时候,ref修饰的参数必须要有值,但是out可以使用一个未赋值的变量作为参数传递。

    上代码:

    void Function1(ref int num)
    {
        num = 999;
    }
    
    void Function2(out int num)
    {
        num = 999;
    }
    
    int number1;
    int number2;
    Function1(ref number1); // 此处会报错,ref修饰的参数必须要有值。
    Function2(out number2); // 不会报错,out可以使用一个未赋值的变量作为参数传递。
    Console.WriteLine(number1);
    Console.WriteLine(number2);

    另外需要注意一个点,对于引用类型,如果在方法体内使用了重新声明如使用new 等,此时引用类型的变量会产生一个新地址,方法内做修改等操作时并不会将对象的值传递出去,此时也可以使用ref或out,保持引用地址。

    总结

    当我们想将值类型在方法内部的的修改传递到外部时,可以使用ref或out修饰符,某些时候,引用类型的更改也可以使用ref或out来传递数据变更,ref和out可以让我们更好的理解值类型和引用类型的区别。

  • 相关阅读:
    UVA
    剑指offer 面试题11
    SharePoint 2013+ Sqlserver 2014 Kerberos 配置传奇, 最终的解决方案 验证。
    ASC(1)G(上升时间最长的序列)
    J2EE它是一个框架?平台?规范?
    C++和python使用struct传输二进制数据结构来实现
    前端开发面试题集(二)
    C语言中<CR>是什么意思
    Delphi ParamStr 使用方法
    打包工具 使用帮助 inno setup
  • 原文地址:https://www.cnblogs.com/pikaqiu/p/14314604.html
Copyright © 2011-2022 走看看