2010-07-31 57 views
0

我已经创建了一个类,它接受一个参数作为参数。当它在构造中使用这个对象时,它是空的。为什么它保持空(未初始化)?如何在C#中使用ref#

// example code, not real 
class Test{ 
    object parent; 

    public Test (ref object _parent) 
    { 
     parent = _parent; 
    } 
} 

object n = null; 
Test t = new Test (ref n); 
n = new Something(); 

当我用不同类(http://pastebin.com/PpbKEufr)试了一下,留下空

+0

这是为什么被压低投票? – 2010-07-31 12:46:01

+0

@Merlyn因为运行代码需要更少的时间,并且看看会发生什么,而不是将它发布到SO上。更好的问题会问*为什么*。 – dbkk 2010-07-31 12:52:00

+0

@dbkk:问题可能不是完美的措词,但将其解读为“为什么会发生这种情况”或“我怎样才能让它做我想做的事情”。 – 2010-07-31 12:56:46

回答

4

是的,parent将留null无论你最终分配给变量nref关键字将实际引用传递给n(与其副本相反)到您的方法中,并且通常在您的方法旨在将新对象实例分配给参数时使用。

在您的方法中,您正在制作n指向的参考副本,在此例中为null。当该方法完成时nparent指向null。当您稍后分配给n时,您并未更改n和父点的对象,而是要求n指向新位置,而parent仍指向null

如果您要创建对象的实例并将其指定给n,那么parent将指向同一对象,并且对该类的任何更改都将可见。如果您没有传递参数ref,情况也会如此,因为参考副本也会指向同一个对象实例。

希望有所帮助。

1

在C#裁判参数引用的实例“指出”通过论证。

例如,如果你在构造改变_parent并将其存储在其他情况下,则n将随之改变。

在发布代码你复制引用的实例(null)到parent。意思是,它将引用的实例复制到字段中,而不是参数本身的引用。

例如,方法改变裁判论点:

public void M(ref object arg) 
{ 
    arg = new object(); 
} 

以及使用例如:

[Test] 
public void SetReferenceArgument() 
{ 
    var myClass = new MyClass(); 
    object arg = null; 
    myClass.M(ref arg); 

    Assert.That(arg, Is.Not.Null); 
} 

REF参数让我们指定实例成将两者在改变基准参数方法和调用者的上下文中。

2

这是不可能的,因为这将打破encapsulation的想法改变一个类的私人成员。

为了更改(即替换)存储在专用字段中的对象,您必须通过该类的公共属性或方法明确地执行此操作。

class Test 
{ 
    object parent; 

    public Test (ref object _parent) 
    { 
     parent = _parent; 
    } 

    public object Parent 
    { 
     get { return parent; } 
     set { parent = value; } 
    } 
} 

object n = null; 
Test t = new Test (ref n); 
n = new Something(); 
t.Parent = n; 

这样,语言可以确保对象的数据不会(意外)从外部改变,这可能会导致最奇怪的效果。