如何在C#中使用ref

时间:2010-07-31 12:31:20

标签: c#

我创建了一个类,它通过ref将对象作为参数接收。当它在它的构造中使用此对象时,它为null。为什么它保持为空(未初始化)?

// 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)时,它保持为空

3 个答案:

答案 0 :(得分:4)

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

在您的方法中,您正在复制n指向的引用,在本例中为null。当方法完成时,nparent都指向null。如果以后分配给n,则表示您没有更改n和父点的对象,而是要求n指向新位置,parent仍然指向null }。

如果您要创建对象的实例并将其分配给n,那么parent将指向同一个对象,并且您的类可以看到对该对象属性的任何更改。如果您没有将参数作为ref传递,则情况也是如此,因为引用副本也会指向同一个对象实例。

希望有所帮助。

答案 1 :(得分: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;

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

答案 2 :(得分:1)

C#中的ref参数引用参数“指向”的实例。

例如,如果您在构造函数中更改 _parent 并将其存储在其他实例中,则 n 也会更改。

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

例如,更改ref参数的方法:

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参数允许我们将一个实例分配给参数,该参数将在方法和调用者的上下文中更改引用。