Question

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();

Was it helpful?

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

OTHER TIPS

No, assingning is not a "new" statement, it copies.... a reference, it does not create a new object. For a class.

For a struct, it does so.

I suggest learning C# by reading the documentation or a book - those basics are normally handled to great detail in those.

You will not go far wrong if you think of every reference type variable, field, parameter, array slot, or other such storage location, has holding either "null", or "object #24601" [or some other number]. There are really only a handful things that can be done with references:

  1. You may create a null reference

  2. You may ask the system to create a new object and return a reference to it

  3. You may copy one reference to another

  4. You may check whether two references are equal to each other, or whether one is equal to null.

  5. You may ask the system to perform some action upon the object identified by a reference

If myCar is a variable of some reference type, a statement like myCar.Color = CarColors.Blue won't affect the variable myCar at all. Instead, it will observe that myCar holds [e.g.] "Object #8675309", and then ask the system to access the Color property or field of object #8675309. Conversely, if otherCar happens to hold "object #90210", a statement of the form otherCar=myCar won't do anything with object #8675309, nor object #90210, but will instead replace the "90210" stored in otherCar with "8675309".

Objects are guaranteed to exist as long as any form of reference to them exists, but if there are two objects which, although referenced by each other, are not referenced by anything else in the universe, both objects may simultaneously cease to exist. This rule is absolute, but there are a couple of twists: code may request a WeakReference to an object; an object is guaranteed to exist as long as a weak reference to it exists, but if the system discovers that no strong references to an object exist, it will invalidate every WeakReference to it. Further, the system keeps a list of all objects that have would like to be notified if they are abandoned. If the system finds that this list holds the only reference to an object, it will move the object to a strongly-referenced list of objects whose Finalize method should run at the first convenient opportunity. When the object's Finalize method is run, the reference will be removed from that latter list. If no reference to the object has been stored anywhere in the mean time, the object will cease to exist.

I have replaced GC.SuppressFinalize with GC.Collect() in dispose function, however this is not freeing the memory.. and am receiving 1000 as a result.

I guess, as it holds other reference(the variable h), GC will not free the memory, even if we invoked it explicit.

So we can very well pass and assign the objects irrespective of the allocated(new) object going out of scope.

Please correct me If i am wrong.

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