c#中的ref用法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#中的ref用法相关的知识,希望对你有一定的参考价值。
可以理解为类似的传址引用,同时还有out。在函数需要外部传入一个变量名,然后在程序内部可以将这个值进行修改,典型的传址引用!在定义时必要加ref或out说明!
public void MethodA(out string s )
s = "1";
调用时,应该先声明一个字符变量。
string temp;
MethodA(out temp);
此时可以打印temp的值会变作"1";
而ref与out基本是类同的,如果在程序中引用原值的话,必须使用ref防止传入未初始化的值。
public void MethodB(ref int s)
s = s*s;
因为该函数要使用形参的原值,所以这里必须使用ref声明,不要使用out声明。
使用时,
int temp = 8;
MethodB(ref temp);
打印temp的值会变为64。
ref因为对原值进行了引用,所以ref要求传入的一定是一个初始化后的值,不能是未初始化的值。
int temp;
MethodB(ref temp);
//原则上这样是会错的,但这里我使用了一个int,由于在声明时int temp与int temp =0 是等价的,所以不会出错,但如果是字符串,使用这种方式完全是可以报错的!因为string temp与string temp ="";是不等价的,你也可理解为必须赋值后才可以使用。
public void MethodC(ref string s)
.......
string temp;
MethodC(ref temp);//这种就是错误的方式。ref要求必须形参已经赋值(初始化)。
string temp = "";
MethodC(ref temp);//这种方式就是正确的。
我们定义成员方法时,如果有引用原值使用必须使用ref,防上对方传入一个未初始化的值,引发程序错误,而没有必要对形参的值有要求时,则尽量使用out,防止调用时增加客户端代码量。
希望能解决您的问题。 参考技术A void fun(ref int a)
a+=1;
int i=2;
fun(ref i);
//i=3
在 C# 中使用“ref”关键字 [重复]
【中文标题】在 C# 中使用“ref”关键字 [重复]【英文标题】:Use of 'ref' keyword in C# [duplicate] 【发布时间】:2011-06-16 07:17:07 【问题描述】:可能的重复:Why use ref keyword when passing an Object?When to pass ref keyword in
C# 中“ref”关键字的正确用法是什么。我相信已经有很多关于此的讨论线程,但我不清楚的是:
-
如果要传入引用对象,是否需要 ref 关键字?我的意思是当你在堆中创建一个对象时,它并不总是通过引用传递。这是否必须明确标记为参考?
【问题讨论】:
大量重复...Why use ref keyword when passing an Object?、C# ref keyword usage、When to pass ref keyword in、When is using the C# ref keyword ever a good idea? 等。所有这些似乎都回答了您的问题。有没有他们没有解决的数字 2? 还必须阅读我们自己的 Jon Skeet 关于该主题的文章:Parameter passing in C#。不幸的是,我不能投票关闭作为该副本的副本。 ;-) 【参考方案1】:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace InOutRef
static class InOutRef
public static void In(int i)
Console.WriteLine(i);
i=100;
Console.WriteLine(i);
public static void Ref(ref int i)
Console.WriteLine(i);
i=200;
Console.WriteLine(i);
public static void Out(out int i)
//Console.WriteLine(i); //Error Unsigned Ref
i=300;
Console.WriteLine(i);
class Program
static void Main(string[] args)
int i = 1;
InOutRef.In(i); //passed by value (in only)
Debug.Assert(i==1);
InOutRef.Ref(ref i); //passed by ref (in or out)
Debug.Assert(i == 200);
InOutRef.Out(out i); //passed by as out ref (out only)
Debug.Assert(i == 300);
我的回答不能再直白了。当使用 in 时,代码将不会记住引用更改,例如经典的 Java 交换 question。但是,当使用 ref 时,它将类似于 VB.NET,因为它会记住 in 和 out 的变化。如果您使用 out 参数,则意味着必须在返回之前声明它(这是由编译器强制执行的)。
输出: 1 //1 来自主 100 //100 来自 in 1 //1 不会从 In 中记住 200 //200 来自参考 //此处应为 200,但 out 强制输出参数(未打印,因为已注释掉) 300 //300 只出 按任意键继续 。 . .【讨论】:
【参考方案2】:这里的答案中有很多令人困惑的错误信息。理解这一点的最简单方法是放弃“ref”意味着“通过引用”的想法。更好的思考方式是“ref”的意思是“我希望被调用方的这个形式参数成为调用方特定变量的别名”。
当你说
void M(ref int y) y = 123;
...
int x = 456;
M(ref x);
也就是说“在调用 M 期间,被调用方的形参 y 是调用方变量 x 的另一个名称”。将 123 分配给 y 与将 123 分配给 x 完全相同,因为它们是同一个变量,一个有两个名称的变量。
就是这样。不要考虑引用类型或值类型或其他任何东西,不要考虑按引用传递或按值传递。所有“ref”的意思是“暂时为这个变量命名”。
【讨论】:
【参考方案3】:使用ref
表示将引用 传递给函数。
默认行为是函数接收对同一对象的新引用。这意味着如果您更改引用的值(例如,将其设置为新对象),那么您将不再指向原始的源对象。当您使用 ref
传递时,更改引用的值会更改源引用 - 因为它们是相同的。
考虑一下:
public class Thing
public string Property get;set;
public static void Go(Thing thing)
thing = new Thing();
thing.Property = "Changed";
public static void Go(ref Thing thing)
thing = new Thing();
thing.Property = "Changed";
然后如果你运行
var g = new Thing();
// this will not alter g
Go(g);
// this *will* alter g
Go(ref g);
【讨论】:
+1 最后,一个正确的答案。把这样的问题留得太久是很危险的,因为那里有太多的错误信息。很高兴在这里使用除反对票以外的其他东西。 害怕有人反对这个;我不想和那个人一起工作! 可能有人对这里给出的答案的大量反对票感到不安。这是我没有尝试提供自己的主要原因。更糟糕的是想象与仍然在 cmets 中尝试和争论的人一起工作。【参考方案4】:我相信 ref 关键字表明您通过引用而不是值传递对象。例如:
void myfunction(ref object a)
a = new Something();
会改变调用函数中a的值 不过,
void myfunction(object a)
a = new Something();
将在本地更改 a 的值,但不会在调用函数中更改。您仍然可以更改项目的属性,但不能设置项目本身的值。例如; a.someproperty = value;
在这两种情况下都可以使用。
【讨论】:
第二个例子(没有 ref)将无法编译,因为这就像说 1 = 3。1 不可能等于 3。但是,使用 ref。好像在说。 x = 1。然后 x = 3。 第二个例子会“工作”,但可能会产生意想不到的结果! 我猜它编译,但它不会改变调用函数上下文中 a 的值。 在对a
的引用在本地成功重新分配的意义上是可行的。但这种变化不会反映回调用函数。它肯定不会导致编译时错误。以上是关于c#中的ref用法的主要内容,如果未能解决你的问题,请参考以下文章