在C#中调用方法不引用在其他类的方法中初始化的对象

时间:2013-08-29 19:28:06

标签: c# objectinstantiation

我有一个我声明一个对象的类,但是没有初始化该对象。然后我将对象传递给另一个类中的方法进行初始化。我期望发生的是调用类中的对象现在将具有对初始化对象的引用,但它是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则可行。任何人都可以解释为什么需要它吗?

6 个答案:

答案 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();
}

这样就无需使用refout传递。

答案 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();
}

或者,您可以使用传递引用,将引用(或指针,如果您熟悉它)传递给函数,因此对该引用所做的更改将反映在函数范围之外。