Change class property value in method

12.8k views Asked by At

I have following code

public class Myclass
{
    public int someProp{ get; set; };
}
public class Program
{
    public static void Main(string[] args)
    {
        Myclass m = new Myclass();
        Console.WriteLine(m.someProp);
        ChangeValue(m);
        Console.WriteLine(m.someProp);
        SetToNull(m);
        Console.WriteLine(m.someProp);
        Console.ReadKey();
    }
    static void ChangeValue(Myclass m)
    {
        m.someProp = 10;
    }
    static void SetToNull(Myclass m)
    {
        m = null;
    }
}

The result is 0 10 10
I'm wondering why after I set the class to null it shows 10.
Is the m which is pass to the method is a copy of the object or it's just reference.

4

There are 4 answers

1
mm8 On BEST ANSWER

Is the m which is pass to the method is a copy of the object or it's just reference.

You are passing a copy of the "m" reference to the methods. If you want to pass the actual reference to the MyClass object in memory you could use the ref keyword:

public class Program
{
    public static void Main(string[] args)
    {
        Myclass m = new Myclass();
        SetToNull(ref m);
        if(m == null)
            Console.WriteLine("NULL!");
        Console.ReadKey();
    }

    static void SetToNull(ref Myclass m)
    {
        m = null;
    }
}

Then the SetToNull method will set the actual "m" reference to a null reference.

0
Justin Niessner On

The m passed around is just a reference.

When you set a property of the object, you're changing a property of the referenced object.

When you set m itself to null, you're changing what m references which is why your original reference in Main still points to the original object.

0
HaimYuhter On

First i want to notice that you are asking about field and not an attribute, attribute are configured this way:

public class Myclass
{
    public int someProp{ get; set; }
}

About Your Question you are right, when you pass a instance to method you are passing a "pointer" to this instance, you cannot replace the instance itself this way, you can just change it properties/fields. in order to replace/change the instance itself you need to pass a reference using the ref keyword.

the fixed code will be:

public class Myclass
{
    public int someProp;
}
public class Program
{
    public static void Main(string[] args)
    {
        Myclass m = new Myclass();
        Console.WriteLine(m.someProp);
        ChangeValue(m);
        Console.WriteLine(m.someProp);
        SetToNull(ref m);
        Console.WriteLine(m.someProp);
        Console.ReadKey();
    }
    static void ChangeValue(Myclass m)
    {
        m.someProp = 10;
    }
    static void SetToNull(ref Myclass m)
    {
        m = null;
    }
}

some places to read for more information:

0
volatilevar On

Using your SetToNull function as an example, it can be rewritten as below. Thus you can see you are not changing the value of m in your main function, but _m instead. _m is also a reference, which is a copy of m.

static void SetToNull(Myclass _m)
{
    _m = null;
}