2010-12-21 63 views
0

可能重复:
When to pass ref keyword in当在一个方法中通过ref传递并且在C#中没有引用时有什么区别?

大家好,

我只是惊讶,为什么我们在C#中有ref,而默认的一切是在C#中的引用类型作为参考传递。

在简单的话,任何人都可以给我解释一下这两种方法之间的区别来电:

public void Test(SomeClass someClass) 
{ 
    // some code here 
} 

public void Test(ref SomeClass someClass) 
{ 
    // some code here 
} 

在我的思想它们都具有参考相同的内存位置。

那么,为什么我们需要关键字ref呢?

回答

2

当你传递一个对象时,你通过引用传递它。这意味着你对该对象所做的任何事情都会在方法返回后反映到对象中。当您通过引用传递引用,即void Foo(ref object obj)时,您正在传递该对象的地址。然后,您可以在地址重新分配给不同的对象,这将是国家的事情,当该方法返回

foo (object o) 
{ 
    ... 
} 

var v = new object(); 
foo(v); 

v仍然会引用在调用之前实例化foo的同一对象

void bar(ref object o) 
{ 
    o = null; 
} 

var v = new object(); 
foo(ref v); 
// v is now null 
8

ref关键字将引用传递给存储引用的任何位置。这允许你从被调用的函数中操纵这个变量。这对值类型特别有用,但在与引用类型一起使用时也有用处。 (Dictionary.TryGetValue()是一个很好的例子的out参数是必需的,返回存储在字典的值out相当于ref不同之处在于它会经历一组不同的编译时检查的。)

例如:

public void Test(ref SomeClass obj) 
{ 
    obj = null; 
} 

public void Test2(SomeClass obj) 
{ 
    obj = null; 
} 

public void Foo() 
{ 
    SomeClass obj = new SomeClass(); 
    Test(ref obj); 
    // obj is null here! 

    obj = new SomeClass(); 
    Test2(obj); 
    // obj is not null here. 
} 
+0

在调用test2之后,obj确实是null – Chandu 2010-12-21 21:00:23

+4

@Cyber​​nate:不,它不会。编译并为自己测试。 `Test2`中的`obj = null`行只会将参数变量设置为null;它不会影响`Foo`中的`obj`本地。 – cdhowie 2010-12-21 21:01:19

+0

我的不好...你是对的。今天学到了一件新事物:)。将我的投票添加到答案... – Chandu 2010-12-21 21:05:29

3

我只是感到惊讶,为什么我们在C#中引用默认情况下,一切都是C#中的引用类型作为引用传递。

因为C#中的某些东西是值类型,有时我们想要通过这些值。我们有ref关键字,以便这些东西可以通过引用传递。

3

它类似于C++中SomeClass *SomeClass **之间的区别。

使用SomeClass *(或没有ref),我们可以修改指向的对象,但是我们不能将它重定向到一个全新的对象。

使用SomeClass **(或使用ref),我们可以更改调用代码中的参数,以便将其指向我们选择的对象。

0

假设方法Foo按值接受一个Bar。如果我有一个名为“博兹”吧,语句:

 
    Foo(Boz); 

可能采取目的在于通过博兹指出,改变该对象的特征,但它不能改变对象博兹点。相反,如果Boz被引用通过,同样的陈述可能导致Boz完全指向一个不同的对象。

作为使用示例,请考虑接受数组作为参数的例程。如果数组按值传递,则收件人可以更改数组中任何项目的值,但收件人无法更改大小。更改数组大小的唯一方法是创建一个新数组,将旧数据项复制到该数组中,然后使用新数组而不是旧数组。当数组按值传递时,接收者无法告诉调用者应该停止使用旧数组,而是使用新数组。通过引用传递的数组不是问题。

相关问题