[C#] out vs ref

当需要从一个方法中有多个返回值时可以考虑使用out和ref这两个关键字。下面通过代码的方式来说明两者的用法和不同之处。

例如现在有一个如下的Add方法,Add方法只有一个返回值。

    static int Add(int num1, int num2)
    {
        return num1 + num2;
    }

把这个例子修改的复杂点,现在需要有4个返回值。这时候out关键字就派上用场了。

    static void Maths(int num1, int num2)
    {
        int add = num1 + num2;
        int sub = num1 - num2;
        int divide = num1 / num2;
        int multi = num1 * num2;
    }

上述代码中,我想将计算后的add,sub,divide,multi四个值均返回给调用方法。使用out关键字来改造这个方法。

    static void Maths(
        int num1,
        int num2,
        out int add,
        out int sub,
        out int divide,
        out int multi)
    {
        add = num1 + num2;
        sub = num1 - num2;
        divide = num1 / num2;
        multi = num1 * num2;
    }

使用下面的代码调用改造后的Maths方法

    int add, sub, multi, div = 0;

    Maths(10, 10, out add, out sub, out multi, out div);

两个注意点:

1. 调用方法和被调用方法需要返回值的参数需要使用out修饰;
2. 在调用方法中,不需要给out参数赋值。即使赋值了,在被调用方法中也会被重新计算。

再来看另一个关于交换两个数值的例子,

    static void Swap(int num1, int num2)
    {
        num1 = num1 + num2;
        num2 = num1 - num2;
        num1 = num1 - num2;
    }

使用ref关键字改造这个方法,

    static void Swap(ref int num1, ref int num2)
    {
        num1 = num1 + num2;
        num2 = num1 - num2;
        num1 = num1 - num2;
    }

在调用方法中,需要添加ref关键字修饰

    int num1 = 10;

    int num2 = 20;

    Swap(ref num1, ref num2);

使用ref修饰的参数,会把在调用方法中的数据传递到被调用方法中。当被调用方法中修改了ref修饰参数的值,调用方法中的相应的参数值也会同时被修改。下面通过一张图来表示out和ref的使用及参数关系。

总结:

当需要有多个返回参数时可以考虑使用out/ref参数;

ref数据的修改是双向的;

out数据只从被调用方法传递至调用方法,如果调用方法给out参数赋值,被调用方法会忽略掉这些数据。

感谢您的阅读~

时间: 2024-10-12 10:51:41

[C#] out vs ref的相关文章

ref和out的用法和区别。

关于ref和out的用法和区别在网上已经有很多的解释,这里只不过是写下对于我而说比较容易理解的解释. ref和out都可以用来在函数中返回数据,类似于c++中指针. 参数 Ref Out 是否一定需要初始化 是 否 机制 传递参数的地址,例如声明了int i=0; i是存储在内存堆的一个地址0x000001那么传递的便是这个地址0x000001 不需要初始化,也就是没有为定义的变量开辟存储空间.在函数体中定义,故只是返回值.(如果之前有定义,则在函数体中清空后再赋值) 一般用途 调用的方法修改传

Oracle PLSQL Demo - 16.弱类型REF游标[没有指定查询类型,已指定返回类型]

declare Type ref_cur_variable IS REF cursor; cur_variable ref_cur_variable; rec_emp scott.emp%RowType; v_sql varchar2(100) := 'select * from scott.emp t'; begin Open cur_variable For v_sql; Loop fetch cur_variable InTo rec_emp; Exit When cur_variable

ref in out params

参数类型可以分为ref.in.out这三种,默认的都是in. 通过引用传递参数, 可使用ref或out关键字.ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量.它们的区别是: 1.把未赋值的变量用作ref参数是非法的,但可以把未赋值的变量用作out参数.在函数使用out参数时,必须把它看成是尚未赋值,调用代码可以把已赋值的变量用作out参数,但存储在该变量中的值会在函数执行时丢失. 以下是关于out使用的一个示例 using System; using System.C

[当我在研究Cocos-2dx的源代码时,我在想什么]-Ref类,一切的起源

[名词解释] 引用计数:引用计数是现代内存管理中常常使用到的一个概念.它的基本思想是通过计数方式实现多个不同对象同一时候引用一个共享对象,详细地讲,当创建一个对象的实例并在堆上分配内存时,对象的引用计数为1,在其它对象中须要持有这个共享对象时.须要把共享对象的引用计数加1.当其它对象不再持有该共享对象时,共享对象的引用计数减1,当共享对象的引用计数变成0时.对象的内存会被马上释放.(部分截取自维基百科). 比較著名的使用引用计数的有COM和Objective-C,在COM的IUnknow接口中定

C#中三个关键字params,Ref,out

关于这三个关键字之前可以研究一下原本的一些操作 using System; using System.Collections.Generic; using System.Text; namespace ParamsRefOut { class Program { static void ChangeValue(int i) { i=5; Console.WriteLine("The ChangeValue method changed the value "+i.ToString())

ref、out 修饰符

ref参数和out参数类似,除了: 1.ref参数要求在传入函数之前赋值,而out参数不用 2.out参数必须在函数结束之前被赋值,而ref参数不用 ref传递参数 若int x;则报错 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 int x=0; 6 Foo(ref x); 7 Console.WriteLine(x);//1 8 Console.ReadKey(); 9 } 10 static void Foo(re

ref out params

ref侧重于将一个值传入函数进行处理,再将处理后的值返还回去:参数是在函数外进行赋值.--将值类型传递转换成引用类型传递 out侧重于函数需要返回多个值:参数是在函数内进行赋值,函数外只进行声明数据类型. params可变参数 out实例: 1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.IO; 5 using System.Linq; 6 using S

C# 基础(一) 访问修饰符、ref与out、标志枚举等等

C# 基础(一) 访问修饰符.ref与out.标志枚举等等 一.访问修饰符 在C#中的访问修饰符有:private.protected.internal.public public:公共类型,同一程序集或其他程序集都可以访问此成员 private:私有类型,同一类里或结构里才可以访问此成员 protected:保护类型,同一类里或者派生类中才可以访问此成员 internal:内部类型,只有在同一程序集才可以访问此成员 访问性不一致:子类的访问权限不能比父类高.防止暴露父类的信息.. 二.stat

C#基础-out与ref字段

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { string outString = "This is the outString value"; Console.WriteLine(outString

what' s ruby?(ref: ruby编程语言)

q1: irb(main):001:0> tmp=(1..10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] irb(main):002:0> tmp.each.class => Enumerator irb(main):003:0> tmp.select.class => Enumerator irb(main):004:0> tmp.map.class => Enumerator irb(main):005:0>