Sean C.
Sean C.

Reputation: 1603

Assign NULL to parameters in method

I know reference types passed to a method can be modified. But I found that it only takes effects on the parameter's members, not the param itself. Here is a test:

That is a reference type:

class MyClass
{
    public int PropInt { get; set; }

    public string PropStr { get; set; }

    public int FieldInt;

    public string FiledStr;
}

This method modifies its members:

void MyFun(MyClass myClass)
    {
        myClass.PropInt = 3;
        myClass.FieldInt = 4;
        myClass.PropStr = "c";
        myClass.FiledStr = "d";
    }

This modifies itself(null or new):

void MyFunNull(MyClass myClass)
    {

        myClass = new MyClass();
        //myClass = null;
    }

Initializing:

MyClass myClass = new MyClass
        {
            PropInt = 1,
            FieldInt = 2,
            PropStr = "a",
            FiledStr = "b"
        };

Test:

---> output {1, 2, "a", "b"}
MyFun(myClass); ---> output {3, 4, "c", "d"}
MyFunNull(myClass); ---> output {3, 4, "c", "d"}

How is that happening? do I have to use out/ref in this case?

Upvotes: 1

Views: 74

Answers (1)

loopedcode
loopedcode

Reputation: 4893

This is because reference of the object in parameter will stay same within your method (unless you explicitly reassign). when you only change its properties, there is no impact on the original instance. When method completes, caller can still access the original object and see the changed properties. Original instance in parameter stayed same as the incoming reference from the caller.

When you change the parameter with a new or reassignment, caller is never aware of this change unless you change the method signature with out or ref.

If you want caller to be aware of a reference type being reassigned or instantiated in a method, you will need to modify it with ref keywoard (see msdn)

For example:

public void Foo(ref MyClass bar)
{
   // Caller will get this new instance back
   // after method completes.
   bar = new MyClass()
}

Changing the reference: following example changes the parameter to some preexisting local reference.

private MyClass myLocalBar
public void Foo(ref MyClass bar)
{
   // Caller will get the modified reference
   bar = this.myLocalBar;
}

You can also use out (msdn) keyword do something similar. But unlike ref, out will require that you assign a value to the out parameter. Attempting to complete the method before an assignment is done to out parameter will generate compiler error.

public void Foo(out MyClass bar)
{
   // We must assign a value to bar
   bar = new MyClass()
}

Following will generate error (un-comment last line to fix)

public void Foo(out MyClass bar)
{
   // We must assign a value to bar
   // Even null assignment is ok:
   // bar = null;
}

out parameter always guarantees the caller that a new/different reference would be coming back. Whereas, ref tells the caller that the method may or may not modify the original reference.

Upvotes: 2

Related Questions