我正在努力如何在真实应用中使用“ref”(通过引用传递参数)。我想有一个简单而有意义的例子。到目前为止我发现的所有内容都可以通过向方法添加返回类型来轻松重做。 有人在想吗? 谢谢!
答案 0 :(得分:20)
我脑海中最好的例子是交换两个变量值的函数:
static void Swap<T>(ref T el1, ref T el2)
{
var mem = el1;
el1 = el2;
el2 = mem;
}
用法:
static void Main(string[] args)
{
string a = "Hello";
string b = "Hi";
Swap(ref a, ref b);
// now a = "Hi" b = "Hello"
// it works also with array values:
int[] arr = new[] { 1, 2, 3 };
Swap(ref arr[0], ref arr[2]);
// now arr = {3,2,1}
}
如果没有ref
关键字,就无法完成此功能。
答案 1 :(得分:5)
一个可能的角落案例:Interlocked.Increment
。如果不通过引用传递变量,就无法以原子方式执行增量。
我不能说我自己非常使用ref
,说实话 - 我通常不需要返回多个值,即使那时out
通常也是 足够了。我使用 ref
的许多情况都是由于作者不理解在参考类型时.NET中如何传递参数。
答案 2 :(得分:4)
框架中内置的TryParse
方法是典型示例。他们使用out
而不是ref
,但它是相同的语义,只是调用者不需要初始化值。例如:
int result;
bool isSuccess = int.TryParse("some string", out result);
if (isSuccess)
{
// use the result here
}
正如您所看到的,该函数返回一个布尔值,指示操作是否成功,但实际结果是否作为out
参数返回。
答案 3 :(得分:1)
public static void Main(string args[])
{
int i=0;
AddSomething(ref i);
AddSomething(ref i);
AddSomething(ref i);
AddSomething(ref i);
string mystr = "Hello";
AddSomeText(ref mystr);
Console.WriteLine(mystr);
Console.WriteLine("i = {0}", i);
}
public static void AddSomeText(ref string str)
{
str+= " World!";
}
public static void AddSomething(ref int ii)
{
ii+=1;
}
答案 4 :(得分:0)
我看到的最常见的地方之一是在某些框架的Save方法中。
原因在于,在很多情况下,如果将对象序列化到另一台机器然后作为新实例(可能带有一些额外的默认值)返回,则实际上不可能在保存调用上维护相同的对象。在这种情况下,您需要引用显示原始引用不再有效。
至于它的必要性,我无法想出一个需要它的例子。大多数地方都很好。
答案 5 :(得分:0)
我认为一个很好的例子就是蹦床。
这是您使用递归函数并将其重新编写为在一组值上重复调用的方法的位置。原因在于,堆栈保持不变,而不是进入堆栈,因为您在每次通话后都会返回,而不是自称。
关心GJ