Question

Consider this code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Foo
    {
        public int x { get; set; }
        public String y { get; set; }

        public Foo()
        {
            this.x = 1;
            this.y = "Jack";
        }
    }

    class Testing
    {
        public static void funcChange(Foo bar)
        {
            bar.x = 2;
            bar.y = "Inga";
        }

        public static void funcNull(Foo bar)
        {
            bar = null;
        }

        public static void Main()
        {
            Foo foo = new Foo();
            Foo foo2 = foo;

            // let's change foo 
            Console.WriteLine("foo before:" + foo.x + " " + foo.y);  // 1 Jack
            funcChange(foo);
            Console.WriteLine("foo after:" + foo.x + " " + foo.y);  // 2 Inga

            // let's null the foo object
            Console.WriteLine("foo before:" + foo.x + " " + foo.y);  // 2 Inga
            funcNull(foo);
            Console.WriteLine("foo after:" + foo.x + " " + foo.y);  // 2 Inga

        }


    }
}

When I run funcChange , then foo changes from 1 Jack to 2 Inga .

When I run funcNull , then foo keeps 2 Inga even after I null foo in funcNull .

From my understanding , C# passing objects by value (I'm not referring to out or ref !!!) .

If so , then why when I run funcChange on foo , then its contents is changing , but when I run funcNull , the foo instance still points to 2 Inga ?

Much appreciated

Was it helpful?

Solution

C# does pass by value by default, however in

funcChange(Foo bar)

bar is a reference to an object of type Foo. This reference is a copy of the input argument, however it refers to the same object on the managed heap. This is why you can mutate bar in funcChange.

In funcNull,

bar = null;

sets the local variable bar to null. Since bar is a copy of the input argument, it does not affect foo in the caller.

OTHER TIPS

your method should be

    public static void funcNull(ref Foo bar)
    {
        bar = null;
    }

and call it like so:

        funcNull(ref foo);

I tried this;

public static Foo funcNull(Foo bar)
    {
        bar = null;
        return bar;
    }



foo = funcNull(foo);

When I run the program there's a runtime error saying that foo doesn't exist when I try to write its values. So this method works.

From my understanding , C# passing objects by value (I'm not referring to out or ref !!!) .

no all class objects are reference types.
But you shouldn't confuse the concept of passing by reference with the concept of reference types. if you declare your method like this you should be able to change the underlying argument variable

public static void funcNull(ref Foo bar)
        {
            bar = null;
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top