C#中关键字ref与out的区别【转】
|
在C#中,ref与out是很特殊的两个关键字。使用它们,可以使参数按照引用来传递。 |
首先,我们来看一个简单的例子:
static void TestRefAndOut(){
string s1 = "Good Luck!";
TestRef(ref s1);
Console.WriteLine(s1);//output: Hello World!
}
static void TestRef(ref string str){
str = "Hello World!";
}
在TestRefAndOut()中将字符串s1以ref关键字的方式传到方法TestRef(ref string str)中,在这个方法中,我们改变了s1的引用变量str的值,最后,回到TestRefAndOut()方法后输出s1的值,发现其值已被改变。
将上例中的ref换成out,代码如下:
{
string s1 = "Good Luck!";
//TestRef(ref s1);
TestOut(out s1);
Console.WriteLine(s1);//output: Hello World!
}
static void TestOut(out string str)
{
str = "Hello World!";
}
同样,在将ref换成out后,会发现最后的输出仍然是相同的,那这两个关键字的区别是什么呢?
进一步测试:
ref:
{
string s1 = "Good Luck!";
TestRef(ref s1);
}
static void TestRef(ref string str)
{
Console.WriteLine(str);//output: Good Lick!
}
out
{
string s1 = "Good Luck!";
TestOut(out s1);
}
static void TestOut(out string str)
{
Console.WriteLine(str);//compile does not pass
}
ref的那段代码顺利编译,输出"Good Luck!",而out那段代码却无法通过编译,提示“Use of unassigned out parameter 'str' ”,即使用了未分配地址的out参数str。怎么回事呢?
原来out参数在进入方法的时候,C#会自动清空它的一切引用和指向,所以在上面的out例子中,必需先要为str参数赋值。如以下程序。
{
string s1 = "Good Luck!";
TestOut(out s1);
}
static void TestOut(out string str)
{
str = "Hello World!";
Console.WriteLine(str);//output: Hello World!
}
Ok,得到第一个区别: out 参数在进入方法(函数)时后清空自己,使自己变成一个干净的参数,也因为这个原因必须在方法返回之前或再使用out参数前为 out 参数赋值(只有地址没有值的参数是不能被.net接受的);而ref参数是不需要在被调用方法使用前先赋值的,甚至也可以被调用方法中不改变ref参数的值,这都不会引起编译错误。
在继续看一段代码:
ref:
{
string s1;
TestRef(ref s1);
Console.WriteLine(s1);//compile does not pass!
}
static void TestRef(ref string str)
{
str = Hello World!";
}
out:
static void TestRefAndOut()
{
string s1;
TestOut(out s1);
Console.WriteLine(s1);//output: Hello World!
}
static void TestOut(out string str)
{
str = "Hello World!";
}
这回发现,ref这段代码无法编译了,s1是一个空引用,所以无法使用。而out参数则因为上述的那个原因,它不在乎s1是不是空引用,因为就算s1不是空引用,它也会把s1变成空引用的。Ok,第二个区别:ref参数在使用前必需初始化,而out不需要。嗯,由上边两个区别可以引申一下,out参数只进不出,ref参数有进有出。在用法上概括一下就是:out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。
C#中关键字ref与out的区别【转】的更多相关文章
- 简述C#中关键字var和dynamic的区别
C#中关键字var和dynamic的区别如下: 1.var申明的变量必须初始化,dynamic申明的变量无需初始化. 2.var关键字只能在方法内部申明局部变量,dynamic关键字可用于局部变量,字 ...
- C#中的ref和out的区别
转载原地址 http://www.cnblogs.com/gjahead/archive/2008/02/28/1084871.html ref和out的区别在C# 中,既可以通过值也可以通过引用传递 ...
- Spring框架xml配置中属性ref与value的区别
1.spring批量扫描mybatis的mapper,使用value 2.spring管理mybatis的单个mapper,用的是ref 虽然引用的是同一个bean,但两个对象的属相类型明显不一样,一 ...
- Python中关键字global与nonlocal的区别
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/xCyansun/article/details/79672634终于下定决心学习Python了.既然 ...
- Java中关键字super与this的区别
一.super关键字 在JAVA类中使用super来引用父类的成分,用this来引用当前对象,如果一个类从另外一个类继承,我们new这个子类的实例对象的时候,这个子类对象里面会有一个父类对象.怎么去引 ...
- 转载 Python中关键字global与nonlocal的区别
转载自CSDN 雁丘1990, 原文地址: https://blog.csdn.net/xcyansun/article/details/79672634 这篇文章写的很赞, 条理清晰, 分析循序渐进 ...
- C#中关键字ref修饰类对象或结构体[转]
using System; using System.Collections.Generic; using System.Text; namespace CSharpTest { struct Dog ...
- Java中关键字throw和throws的区别
==========================================题外话===================================================== 今 ...
- .net 中 ref out params的区别
C#中有三个关键字-ref,out ,params,虽然本人不喜欢这三个关键字,因为它们疑似破坏面向对象特性.但是既然m$把融入在c#体系中,那么我们就来认识一下参数修饰符ref,out ,param ...
随机推荐
- 剑指offer-面试题.二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像. 二叉树节点定义如下: strcut BinaryTreeNode { int val; strcut BinaryTreeNode* m_ ...
- mysql命令具体解释
首先创建一个简单的user表 CREATE TABLE `user` ( `id` int NOT NULL AUTO_INCREMENT , `name` varchar(255) NULL , ...
- PHP流程控制中不经常使用的替代语法
准备做个wordpress的主题.结果看到了例如以下的语法: <div id="primary" class="content-area"> < ...
- SSH2配置事务的两种方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- NET基础课--WinForm开发推荐3
用户体验 较长时间的运算:使用进度条(progress bar) 不要阻塞界面(UI)线程:使用多线程进行长时间的运算 状态栏(status bar)提示应用程序的状态 操作开始之后,用户应当能够通过 ...
- 易语言转C#小试牛刀
呵呵,用了几年的易语言,太郁闷了,玩过E的童鞋们懂得,偶然机会尝试C#,现正式投入C#门下. 我会把我学习C#的一些知识和重点,实时发不到我的BLOG中,同想学习C#的童鞋一起成长起来.
- 11个有用的移动网页开发App和HTML5框架
在过去的两年里,触屏设备飞速增长.iOS和Android设备让开发者和设计师开始重新思考他们的网页应用,以提供更好的触屏体验. 移动Web应用相对于本地的App有很多优势,虽然也有很多设计和开发上的挑 ...
- html5的改变
html5的改变 新增的元素 新增的结构元素 section.article.aside.header.hgroup.footer.nav.figure 新增的其他元素 video.audio.emb ...
- 封装一些数据库SQLCipher的方法(增、删、改、查)
上一篇随笔只是简单的说了一下使用SQLCipher框架,介绍的比较笼统,可能看一遍之后更加蒙圈了,为了更好的使用这个数据库,整理了我在公司项目的需要用的方法,包括创建表,插入数据,更新数据,搜索查询数 ...
- Android中Menu的基本用法
一. 使用xml定义Menu 菜单资源文件必须放在res/menu目录中.菜单资源文件必须使用<menu>标签作为根节点.除了<menu>标签外,还有另外两个标签用于设置菜单项 ...