通常我们向方法中传递的是值,方法获得的是这些值的一个拷贝,然后使用这些拷贝,当方法运行完毕后,这些拷贝将被丢弃,而原来的值不会受到影响。 这种情况是通常的,当然还有另外一种情况,我们向方法传递参数的形式,引用(ref)和输出(out)。

  有时,我们需要改变原来变量中的值,这是我们可以向方法传递变量引用,而不是变量的值,引用是一个变量,他可以访问原来变量的值,修改引用将修改原来变量的值。变量的值存储在内存中,可以创建一个引用,他指向变量在内存中的位置,当引用被修改时,修改的是内存中的值,因此变量的值可以被修改,当我们调用一个含有引用参数的方法时,方法中的参数将指向被传递给方法的相应变量,因此,我们会明白为什么当修改参数变量的修改也将导致原来变量的值被修改。

ref

using System;
using System.Collections.Generic;
using System.Linq; namespace ConsoleAppTest
{
class Program
{
static void Main(string[] args)
{
Gump gump = new Gump();
List<int> list = new List<int>();
double a = ;
gump.AddInt(,ref list);
gump.AddInt(, ref list);
gump.AddInt(, ref list);
Console.WriteLine($"a={a}");
Console.WriteLine(string.Join(",", list.Select(x => x.ToString())));
Console.ReadLine();
}
} class Gump
{
public double Square(ref double x)
{
x = x * x;
return x;
} public void AddInt(int i, ref List<int> list)
{
list.Add(i);
}
}
}

out

using System;
using System.Collections.Generic;
using System.Linq; namespace ConsoleAppTest
{
class Program
{
static void Main(string[] args)
{
Gump doit = new Gump();
double x1 = ;
double cubed1 = ;
double squared1 = ;
double half1 = ;
doit.math_routines(x1, out half1, out squared1, out cubed1);
Console.WriteLine("Before method->x1={0}", x1);
Console.WriteLine("Before method->half1={0}", half1);
Console.WriteLine("Before method->squared1={0}", squared1);
Console.WriteLine("Before method->cubed1={0}", cubed1);
doit.math_routines(x1, out half1, out squared1, out cubed1);
Console.WriteLine("After method->x1={0}", x1);
Console.WriteLine("After method->half1={0}", half1);
Console.WriteLine("After method->squared1={0}", squared1);
Console.WriteLine("After method->cubed1={0}", cubed1);
Console.ReadLine();
}
} class Gump
{
public void math_routines(double x, out double half, out double squared, out double cubed)
//可以是:public void math_rotines(//ref double x,out double half,out double squared,out double cubed)
//但是,不可以这样:public void math_routines(out double x,out double half,out double squared,out double cubed)
//对本例子来说,因为输出的值要靠X赋值,所以X不能再为输出值
{
half = x / ;
squared = x * x;
cubed = x * x * x; } public void AddInt(int i, out List<int> list1, out List<int> list2)
{
//引用类型 out 要先实例化
list1 = new List<int>();
list2 = new List<int>();
if (i % == )
{
list1.Add();
}
}
}
}

通过制定返回类型,可以从方法返回一个值,有时候,需要返回多个值,虽然我们可以使用ref来完成,但是C#专门提供了一个属性类型,关键字为out,介绍完后,我们将说明ref和out的区别。

我们发现,ref和out似乎可以实现相同的功能,因为都可以改变传递到方法中的变量的值,但是二者本质的区别就是,ref是传入值,out是传出值,在含有out关键之的方法中,变量 必须有方法参数中不含out(可以是ref)的变量赋值或者由全局(即方法可以使用的该方法外部变量)变量赋值,out的宗旨是保证每一个传出变量都必须被赋值

在传入变量的时候,out关键字的变量可以不被初始化,但是没有out 关键字的值要被赋值。而ref参数在传递给方法是,就已经被赋值了,所以ref侧重修改,out侧重输出。

参数ref与out的更多相关文章

  1. C#方法中参数ref和out的解析

    一.C#方法中参数类型 有4种参数类型,有时候很难记住它们的不同特征,下图对它们做一个总结,使之更容易比较和对照. 二.C#方法中的参数 1.值参数 使用值参数,通过复制实参的值到形参的方式把数据传递 ...

  2. C#中的out参数/ref参数/params可变参数

    out参数: out关键字 通过引用来传递参数,在定义方法和调用方法的时候都必须使用out关键字 简单来讲out可以用来返回多个参数类型. static void Main(string[] args ...

  3. 浅谈c#的三个高级参数ref out 和Params

    c#的三个高级参数ref out 和Params 前言:在我们学习c#基础的时候,我们会学习到c#的三个高级的参数,分别是out .ref 和Params,在这里我们来分别的讲解一下,在这里的我们先不 ...

  4. C#高级参数ref的使用

    ref关键字用于将方法内的变量改变后带出方法外.具体我们通过例子来说明: 例子中,将变量n1和n2交换了.如果没有加ref参数,由于没有swadDemo()方法没有返回值,调用后,n1和n2是不会交换 ...

  5. 浅谈c#的三个高级参数ref out 和Params C#中is与as的区别分析 “登陆”与“登录”有何区别 经典SQL语句大全(绝对的经典)

    浅谈c#的三个高级参数ref out 和Params   c#的三个高级参数ref out 和Params 前言:在我们学习c#基础的时候,我们会学习到c#的三个高级的参数,分别是out .ref 和 ...

  6. out参数ref参数params 可变参数

    1.我们在主函数中调用其他函数,我们管主函数为调用者,其他函数为被调用者. 如果被调用者,想要得到调用者的值:传参 使用静态字段来模拟全局变量  在方法外类里写字段 public static _na ...

  7. C#返回多个参数 ref及out

    out 关键字会导致参数通过引用来传递.这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化.若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字.例如 ...

  8. C#中引用参数ref和输出参数out

    引用参数 用于按引用传递自变量. 为引用参数传递的自变量必须是具有明确值的变量,并且在方法执行期间,引用参数指明的存储位置与自变量相同. 引用参数使用 ref 修饰符进行声明. 输出参数 用于按引用传 ...

  9. C# 中的三个高级参数 ref

    今天在浏览博文时,看到这篇文章:C#中的ref 传进出的到底是什么 ? 在传对象时使用ref的疑问 引用类型就传的就是地址,值类型传的就是值,可是还仍有那么多人迷惑,网上虽然流传着很多ref 的相关文 ...

随机推荐

  1. .class和.getClass()的区别

    使用指定类初始化日志对象,在日志输出的时候,可以打印出日志信息所在类 如: getClass() 返回此 Object 的运行时类. //需要有com.lpx.test.class这个类 Logger ...

  2. springboot 打war

    pom.xml <packaging>war</packaging> <!-- 打包设置 --> <plugins> <plugin> &l ...

  3. [转载:Q1mi]Bootstrap和基于Bootstrap的登录验证示例

    转载自:Q1mi Bootstrap介绍 Bootstrap是Twitter开源的基于HTML.CSS.JavaScript的前端框架. 它是为实现快速开发Web应用程序而设计的一套前端工具包. 它支 ...

  4. kubernetes 将pod运行在某些特定的节点上,给节点打标签

    给节点打上标签: kubectl label node  <node_name> GPU=true   #打上标签 GPU=true 在创建pod的yaml文件时:  添加 nodeSel ...

  5. BZOJ3864: Hero meet devil(dp套dp)

    Time Limit: 8 Sec  Memory Limit: 128 MBSubmit: 397  Solved: 206[Submit][Status][Discuss] Description ...

  6. Zookeeper与Curator二三事【坑爹】

    起因:我的Dubbo服务起不来:我本地Zookeeper3.4.11,Curator4.1 Caused by: org.apache.zookeeper.KeeperException$Unimpl ...

  7. source insight如何删除没用的project 及其常见问题

    4年09月05日 ⁄ 综合 ⁄ 共 439字 ⁄ 字号 小 中 大 ⁄ 评论关闭 我正在中文路径下加载了一个工程,结果一点击打开,source insight程序就会出现错误提示,要求关闭.我想可能是 ...

  8. Vue(小案例_vue+axios仿手机app)_实现用户评论

    一.前言 1.渲染评论列表 2.点击加载按钮,加载更多    3.提交评论 二.主要内容 1.评论列表一般是注册到一个全局的公共组件中 2.请求后台数据,渲染评论列表 (1)数据格式如下 地址 /ap ...

  9. 优秀的电商平台Jshop栗子

    摘录自:https://blog.csdn.net/chenjun9205/article/details/52412503 下载源代码 git clone https://git.oschina.n ...

  10. dubbo核心要点及下载(dubbo二)

    一.dubbo核心要点 1):服务是围绕服务提供方和服务消费方的,服务提供方实现服务,服务消费方调用服务. 2):服务注册 对于服务提供方它需要发布服务,而由于应用系统的复杂性,服务的数量.类型不断的 ...