Question

I have a class where I declare an object, but don't initialize the object. Then I pass the object to a method in another class for initialization. What I expect to happen is that the object in the calling class will now have a reference to the initialized object, but instead it is null.

Here is an example of what I mean:

class MainClass
{
    ObjectA foo;

    OtherClass.InitializeObjectA(foo);

    // why is foo null over here?
}

class OtherClass
{
    public static void InitializeObjectA(ObjectA device)
    {
        device = new ObjectA();
    }
}

My problem is that device when I try to use foo after calling InitializeObjectA() it is still pointing to null! If I change InitializeObjectA() to out ObjectA device it works. Can anyone explain why this is needed?

Was it helpful?

Solution

If you want this to work, you need to pass by reference:

public static void InitializeObjectA(ref ObjectA device)
{

Or:

public static void InitializeObjectA(out ObjectA device)
{

Without that, InitializeObjectA sets the device parameter to a new ObjectA(), but that will not affect the caller, because, by default, references are passed by value.

Note that, if you're just trying to initialize, returning an instance instead of void is often a better way to handle this:

public static ObjectA InitializeObjectA()
{
     return new ObjectA();
}

This avoids the need to use ref or out passing.

OTHER TIPS

A class is a reference type, you pass the address of foo as parameter (copy), within you change the copy, but the new address won't be set back to the original foo. This will only be done with the out or ref keyword.

The simplest way to create the instance of ObjectA named foo is to return the instance to assign to the variable

class MainClass
{
    ObjectA foo = OtherClass.InitializeObjectA();
}

class OtherClass
{
    public static ObjectA InitializeObjectA()
    {
        return new ObjectA();
    }
}

Why not just have the Initialize method return the created object?

class MainClass
{
    var foo = OtherClass.InitializeObjectA(foo);
}

class OtherClass
{
    public static ObjectA InitializeObjectA(ObjectA device)
    {
        return new ObjectA();
    }
}

From what I understand, the C# compiler doesn't actually initialize variables for you like that. I'm not even able to compile this code in Visual Studio 2010, because it's an error to pass an uninitialized parameter to a function.

You want:

ObjectA foo = null;

Which is I think what you're trying to do anyway, C# just doesn't do it for you as it would in Java. This still doesn't get the behavior I think you're trying to achieve though, which is probably best accomplished by refactoring your code to something like

ObjectA foo = InitializeObjectA()

public static ObjectA InitializeObjectA(){
    return new ObjectA();
}

Alternately, you can use pass by reference, where you pass a reference (or pointer if you're familiar with it) to the function, so changes made to that reference are reflected outside the scope of your function.

That's because when you do

device = new ObjectA();

you are setting the object to a new one, with a different reference in memory.

You should do something like:

class MainClass
{
    ObjectA foo = OtherClass.InitializeObjectA(foo);
}

class OtherClass
{
    public static ObjectA InitializeObjectA(ObjectA device)
    {
        return = new ObjectA();
    }
}

or instead

class MainClass
{
    ObjectA foo = null;
    OtherClass.InitializeObjectA(out foo);
}

class OtherClass
{
    public static void InitializeObjectA(out ObjectA device)
    {
        device = new ObjectA();
    }
}

More information about why this happens can be found here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top