2010-08-05 143 views
2

我看了类似的问题,并阅读了一些文章。 THis文章有一些图片说明了这一点。传递参考和使用参考

SomeObject so = new SomeObject(); 
somefunction(so); 
Console.write(so.x); // will print 1 

SomeObject so1 = new SomeObject(); 
somefunctionByRef(so1); 
Console.write(so1.x); // will print 1 


static void somefunction(SomeObject so) 
{ 
    so.x = 1; 
} 

public void somefunctionByRef(ref SomeObject so) 
{ 
    so.x = 1; 
} 

这两种方法对这个参考类型都有相同的效果。那么为什么选择ref关键字作为参考类型?

使用somefunction(SomeObject所以)并修改方法内的对象并期望更改而不使用ref关键字是一种糟糕的做法(可能为false)?

回答

3

在.Net中传递的默认参数是按值完成的。对于值类型和引用类型都是如此。区别在于,对于引用类型,您将通过值与实际对象传递对实例的引用。

效果是原始函数中的so引用和someFunction是独立的。更改引用所引用的实例对另一个没有影响。然而,因为它们指向同一个对象,他们可以看到的突变被其他做过对象(这就是为什么在你的例子X的变化)

SomeObject so = new SomeObject(); 
so.x = 42; 
somefunction(so); 
Console.Write(so.x); // will print 42 

static void somefunction(SomeObject so) { 
    so = new SomeObject(); 
    so.x = 13; 
} 

ref修饰符使参数通过引用而不是值传递。实际上没有参考文献的副本,so中的原文和调用函数都是相同的参考文献。所以重置一个重置其他

SomeObject so = new SomeObject(); 
so.x = 42; 
somefunction(ref so); 
Console.Write(so.x); // will print 13 

static void somefunction(ref SomeObject so) { 
    so = new SomeObject(); 
    so.x = 13; 
} 
1

我只在处理非参考类型时使用ref,例如INT,小数等

看看this MSDN page为一点更清楚的解释,以及一个有点疑难杂症

1

类是已经通过引用传递(非托管方面的所以是一个指向对象)。传递引用可以让你改变底层变量(你正在使用指向指针的指针)。把这个代码:

static void foo(SomeObject so) 
{ 
    so.x = 1; 
    so = null; 
} 

static void bar(ref SomeObject so) 
{ 
    so.x = 1; 
    so = null; 
} 

SomeObject so1 = new SomeObject(); 
foo(so1); 
Console.write(so1.x); // will print 1 
bar(so1); 
Console.write(so1.x); // crash 

第一种方法将工作,你会打印出1 - 分配这么空只是改变一个变量是本地的功能。第二个会导致崩溃(NullReferenceException),因为so1已被设置为null。

+0

那么为什么选择参考类型ref关键字? – DarthVader 2010-08-05 02:18:54

+0

所以你想要做什么? – ronaldwidha 2010-08-05 02:20:59

+0

通过使用'ref',您可以从不同的函数中更改变量引用的对象。注意赋值'so = null;' – 2010-08-05 02:24:11

0

对于引用类型,默认情况下,参数按引用传递,除非指定按值传递。我认为这是一个安全的假设,大多数.Net开发者应该知道。

+1

默认情况下,它们全都通过_value_传递。 _value_在值类型(对象)和引用类型(对象的引用)之间有所不同。 'ref'和'out'允许通过引用传递。 – 2010-08-05 02:21:42