我创建了一个类,它通过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)时,它保持为空
答案 0 :(得分:4)
是的,parent
将保留null
,无论您最终分配给变量n
。 ref
关键字将实际引用传递给n
(而不是它的副本)到您的方法中,并且通常在您的方法旨在为参数分配新对象实例时使用。
在您的方法中,您正在复制n
指向的引用,在本例中为null
。当方法完成时,n
和parent
都指向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参数允许我们将一个实例分配给参数,该参数将在方法和调用者的上下文中更改引用。