可能重复:
Why use ref keyword when passing an Object?
When to pass ref keyword in
C#中'ref'关键字的正确用法是什么?我相信这方面有很多讨论主题,但我不清楚的是:
答案 0 :(得分:22)
使用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 :(得分:15)
这里的答案中有很多令人困惑的错误信息。理解这一点的最简单方法是放弃“ref”的意思是“通过引用”。考虑它的一个更好的方法是“ref”意味着“我希望被叫方的这个形式参数成为调用方的特定变量的别名”。
当你说
时void M(ref int y) { y = 123; }
...
int x = 456;
M(ref x);
这就是说“在调用M时,被叫方的形式参数y是调用者侧变量x的另一个名称”。将123分配给y与将123分配给x完全相同,因为它们是相同的变量,一个具有两个名称的变量。
这就是全部。不要考虑引用类型或值类型或其他,不考虑通过引用传递或通过值传递。所有“ref”意味着“暂时为此变量创建第二个名称”。
答案 2 :(得分:0)
我相信ref关键字表示您通过引用传递对象,而不是按值传递。例如:
void myfunction(ref object a) {
a = new Something();
}
会改变调用函数中a的值 但是,
void myfunction(object a) {
a = new Something();
}
会改变本地的值,但不会改变调用函数的值。您仍然可以更改项目的属性,但不能设置项目本身的值。例如; a.someproperty = value;
可以在两种情况下都有效。
答案 3 :(得分:0)
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);
}
}
}
我的回答不能再是字面意义了。在中使用时,代码将不会记住参考通道,例如经典Java交换question。但是,当使用 ref 时,它将类似于VB.NET,因为它会记住中的和 out 中的更改。如果使用 out 参数,则表示必须在返回之前声明它(这由编译器强制执行)。
Output: 1 //1 from main 100 //100 from in 1 //1 is NOT remembered from In 200 //200 from ref //should be 200 here but out enforces out param (not printed because commented out) 300 //300 is out only Press any key to continue . . .