Search code examples
c#objectreferencegarbage-collectiondispose

Does assigning an object to other creates a copy?


I tried with the below code, I got the output as 1000. I heard assigning object must share the reference instead of copying the entire object memory. Here the result is different.Can anyone help.

public aaaaa ad = new aaaaa();

static void Main(string[] args)
{
    Program p = new Program();
    p.fun1();
    p.fun2();
}

public void fun1()
{
    using(smallclass s = new smallclass())
    {
        s.j = 1000;
        ad.fun1(s);
    }
}

public void fun2()
{
    ad.fun2();
}
public class aaaaa
{
    public smallclass h = new smallclass();
    public void fun1(smallclass d)
    {
        h = d;
    }
    public void fun2()
    {
        Console.WriteLine(h.j);
    }
}

public class smallclass:IDisposable
{
    public int j = 9;

    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}

Update: I expect an object reference exception as the referenced memory is disposed in p.fun1();


Solution

  • Here is an simple example how assinging works

    using System;
    
    namespace ConsoleApplication1
    {
        internal class Program
        {
            private static smallclass objA = new smallclass();
            private static smallclass objB = new smallclass();
    
            private static void Main(string[] args)
            {
                showValues();
    
                objA.value = 1000;
    
                showValues();
    
                objB = objA;
    
                showValues();
    
                objA.value = 1055;
    
                showValues();
            }
    
            private static void showValues()
            {
                Console.WriteLine("objA.value: " + objA.value);
                Console.WriteLine("objB.value: " + objB.value);
    
                Console.ReadLine();
            }
        }
    
        internal class smallclass : IDisposable
        {
            public int value = 0;
    
            public void Dispose()
            {
                //Here you can remove eventHandlers
                //or do some other stuff before the GC will play with it
            }
        }
    }
    

    Like you can see

    1. first we create 2 objects objA and objB
      than we show the values like expected they are both 0

    2. after that we increase the value of objA to 1000 the value of objA a is 1000 and the value of objB remains at 0

    3. NOW we assingning objA and objB so the value of objB got also 1000

    4. if we now change the value of objA to 1055 the value of objB get also changed because objB is no more an separate object it now holds the same reference like objA does

    EDIT

    And now i will show you how you get your Error based on your example

    change your aaaaa class to:

    public class aaaaa
    {
        public WeakReference<smallclass> h;
        public void fun1(smallclass d)
        {
            h = new WeakReference<smallclass>(d);
        }
        public void fun2()
        {
            smallclass k;
            if(h.TryGetTarget(out k))
            Console.WriteLine(k.j);
            else
                Console.WriteLine("ERROR ERRROR ERROR");
        }
    }
    

    and modify your static void Main(string[] args) to:

        static void Main(string[] args)
        {
            Program p = new Program();
            p.fun1();
            GC.Collect();
            p.fun2();
    
            Console.Read();
        }
    

    Ok lets get through the changes

    we are using the WeakReference<T> (you could also use WeakReference) if the GC now comes across our object he can't find a StrongReference so can Collect it

    now to the GC.Collect() YOU need to call it because it forced the GC to do his work (now at this moment)

    and remember like i told you before IDisposable will get called from the GC before he destroys the object (AFAIK) so there is the place to put all the stuff that need to be done before the object will get destroyed