参数ref与out
通常我们向方法中传递的是值,方法获得的是这些值的一个拷贝,然后使用这些拷贝,当方法运行完毕后,这些拷贝将被丢弃,而原来的值不会受到影响。 这种情况是通常的,当然还有另外一种情况,我们向方法传递参数的形式,引用(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的更多相关文章
- C#方法中参数ref和out的解析
一.C#方法中参数类型 有4种参数类型,有时候很难记住它们的不同特征,下图对它们做一个总结,使之更容易比较和对照. 二.C#方法中的参数 1.值参数 使用值参数,通过复制实参的值到形参的方式把数据传递 ...
- C#中的out参数/ref参数/params可变参数
out参数: out关键字 通过引用来传递参数,在定义方法和调用方法的时候都必须使用out关键字 简单来讲out可以用来返回多个参数类型. static void Main(string[] args ...
- 浅谈c#的三个高级参数ref out 和Params
c#的三个高级参数ref out 和Params 前言:在我们学习c#基础的时候,我们会学习到c#的三个高级的参数,分别是out .ref 和Params,在这里我们来分别的讲解一下,在这里的我们先不 ...
- C#高级参数ref的使用
ref关键字用于将方法内的变量改变后带出方法外.具体我们通过例子来说明: 例子中,将变量n1和n2交换了.如果没有加ref参数,由于没有swadDemo()方法没有返回值,调用后,n1和n2是不会交换 ...
- 浅谈c#的三个高级参数ref out 和Params C#中is与as的区别分析 “登陆”与“登录”有何区别 经典SQL语句大全(绝对的经典)
浅谈c#的三个高级参数ref out 和Params c#的三个高级参数ref out 和Params 前言:在我们学习c#基础的时候,我们会学习到c#的三个高级的参数,分别是out .ref 和 ...
- out参数ref参数params 可变参数
1.我们在主函数中调用其他函数,我们管主函数为调用者,其他函数为被调用者. 如果被调用者,想要得到调用者的值:传参 使用静态字段来模拟全局变量 在方法外类里写字段 public static _na ...
- C#返回多个参数 ref及out
out 关键字会导致参数通过引用来传递.这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化.若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字.例如 ...
- C#中引用参数ref和输出参数out
引用参数 用于按引用传递自变量. 为引用参数传递的自变量必须是具有明确值的变量,并且在方法执行期间,引用参数指明的存储位置与自变量相同. 引用参数使用 ref 修饰符进行声明. 输出参数 用于按引用传 ...
- C# 中的三个高级参数 ref
今天在浏览博文时,看到这篇文章:C#中的ref 传进出的到底是什么 ? 在传对象时使用ref的疑问 引用类型就传的就是地址,值类型传的就是值,可是还仍有那么多人迷惑,网上虽然流传着很多ref 的相关文 ...
随机推荐
- [模板] 次短路 | bzoj1726-[Usaco2006Nov]Roadblocks第二短路
简介 所谓次短路, 顾名思义, 就是第二短路. :P 1到n的次短路长度必然产生于:1到x的最短路 + edge(x,y) + y到n的最短路 简单证明一下: 设 \(dis(i,j)\) 表示 \( ...
- CentOS下安装nvm
1安装版本管理工具git yum install git 查看git版本 git --version 2 安装Node.js版本管理工具nvm curl -o- https://raw.githubu ...
- Go语言协程
协程的特点 1.该任务的业务代码主动要求切换,即主动让出执行权限 2.发生了IO,导致执行阻塞(使用channel让协程阻塞) 与线程本质的不同 C#.java中我们执行多个线程,是通过时间片切换来进 ...
- Android Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > Conflict with dependency
错误内容: Error:Execution failed for task ':app:preDebugAndroidTestBuild'.> Conflict with dependency ...
- jzoj6099. 【GDOI2019模拟2019.4.1】Dist
题目链接:https://jzoj.net/senior/#main/show/6099 考虑直接统计某个点到其它所有点的距离和 我们先把整个团当成一个点建图,处理出任意两个团之间的距离\(dis(i ...
- python学习day11 函数Ⅲ (内置函数与lambda表达式)
函数Ⅲ(内置函数&lambda表达式) 1.函数小高级 函数可以当做变量来使用: def func(): print(123) func_list = [func, func, func] # ...
- Java基础 -- 复用类(组合和继承)
复用类有两种实现方式. 在新的类中产生现有类的对象,由于新的类是由现有类的对象所组成,所以这种方法称之为组合. 采用继承实现. 一 组合语法 下面创建两个类WaterSource和Sprinkler ...
- dubbo核心要点及下载(dubbo二)
一.dubbo核心要点 1):服务是围绕服务提供方和服务消费方的,服务提供方实现服务,服务消费方调用服务. 2):服务注册 对于服务提供方它需要发布服务,而由于应用系统的复杂性,服务的数量.类型不断的 ...
- 第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。
一. 整体说明 揭秘: 通过F12查看Task类的源码(详见下面的截图),发现Task类的构造函数有有一个参数为:TaskCreationOptions类型,本章节可以算作是一个扩展章节,主要就来研究 ...
- ZOC7在Mac下发送命令到多个窗口设置
1 详见截图,找了半天 2 然后,下边框就会出现命令发送多个窗口的输入框了