我有一个我声明一个对象的类,但是没有初始化该对象。然后我将对象传递给另一个类中的方法进行初始化。我期望发生的是调用类中的对象现在将具有对初始化对象的引用,但它是null。
这是我的意思的一个例子:
class MainClass
{
ObjectA foo;
OtherClass.InitializeObjectA(foo);
// why is foo null over here?
}
class OtherClass
{
public static void InitializeObjectA(ObjectA device)
{
device = new ObjectA();
}
}
我的问题是当我在调用InitializeObjectA()
后尝试使用foo时它仍然指向null!如果我将InitializeObjectA()
更改为out ObjectA device
则可行。任何人都可以解释为什么需要它吗?
答案 0 :(得分:5)
如果您希望这个工作,您需要通过引用传递:
public static void InitializeObjectA(ref ObjectA device)
{
或者:
public static void InitializeObjectA(out ObjectA device)
{
如果不这样做,InitializeObjectA
会将device
参数设置为new ObjectA()
,但这不会影响调用者,因为默认情况下,引用按值传递
请注意,如果您只是尝试初始化,则返回实例而不是void通常是处理此问题的更好方法:
public static ObjectA InitializeObjectA()
{
return new ObjectA();
}
这样就无需使用ref
或out
传递。
答案 1 :(得分:1)
那是因为你做的时候
device = new ObjectA();
您正在将对象设置为新对象,并在内存中使用不同的引用。
您应该执行以下操作:
class MainClass
{
ObjectA foo = OtherClass.InitializeObjectA(foo);
}
class OtherClass
{
public static ObjectA InitializeObjectA(ObjectA device)
{
return = new ObjectA();
}
}
或者
class MainClass
{
ObjectA foo = null;
OtherClass.InitializeObjectA(out foo);
}
class OtherClass
{
public static void InitializeObjectA(out ObjectA device)
{
device = new ObjectA();
}
}
可以找到有关为何发生这种情况的更多信息here。
答案 2 :(得分:1)
一个类是一个引用类型,你传递foo的地址作为参数(copy),在你更改副本,但新地址不会被设置回原来的foo。这只能通过 out 或 ref 关键字来完成。
答案 3 :(得分:1)
创建名为foo的ObjectA实例的最简单方法是返回要分配给变量的实例
class MainClass
{
ObjectA foo = OtherClass.InitializeObjectA();
}
class OtherClass
{
public static ObjectA InitializeObjectA()
{
return new ObjectA();
}
}
答案 4 :(得分:1)
为什么不让Initialize方法返回创建的对象?
class MainClass
{
var foo = OtherClass.InitializeObjectA(foo);
}
class OtherClass
{
public static ObjectA InitializeObjectA(ObjectA device)
{
return new ObjectA();
}
}
答案 5 :(得分:1)
据我所知,C#编译器实际上并没有像你那样初始化变量。我甚至无法在Visual Studio 2010中编译此代码,因为将未初始化的参数传递给函数是错误的。
你想:
ObjectA foo = null;
我认为你想要做的是什么,C#只是不像你在Java那样为你做。这仍然没有得到我认为你想要实现的行为,这可能最好通过将代码重构为类似
来实现。ObjectA foo = InitializeObjectA()
public static ObjectA InitializeObjectA(){
return new ObjectA();
}
或者,您可以使用传递引用,将引用(或指针,如果您熟悉它)传递给函数,因此对该引用所做的更改将反映在函数范围之外。