-4

So lets say a create a reference to an unmanaged object...

RandomObject x;

And then i assign that reference to an unmanaged object.

x = new RandomObject(argX, argY);

But later i decide that i want x to reference a different instance of that object:

x = new RandomObject(argZ, argV);

What is happening in this case? Is "new RandomObject(argX, argY)" disposed when i reassign x to a different instance of an unmanaged object? Or do i have to dispose it myself before reassigning? What im asking is the lifetime of this object.

shnk
  • 33
  • 3
  • 1
    You can't directly reference an unmanaged object. Do you mean "A c# object that wraps an unmanaged resource and implements `IDisposable`"? – John Wu Sep 13 '18 at 23:15
  • Yes. That is what i mean sorry. Basically what im asking is what happens to the unmanaged resource when the reference references something else. – shnk Sep 13 '18 at 23:33
  • search for questions on "disposable" and "unmanaged references". THere are more than enough resources on managing unmanaged resources to answer your question. – D Stanley Sep 13 '18 at 23:39

1 Answers1

1

In C#, the garbage collector will manage all object and release the memory of any objects which no longer have any references.

Using your example:

RandomObject x;
// A RandomObject reference is defined.

x = new RandomObject(argX, argY);
// Memory is allocated, a new RandomObject object is created in that memory location, 
// and "x" references that new object.

x = new RandomObject(argZ, argV);
// Memory is allocated, a new RandomObject object is created in that memory location,
// and "x" references that new object. The first RandomObject object no longer has 
// any references to it and will eventually be cleaned up by the garbage collector.

Unmanaged Resources

Even though all objects in C# are managed, there are "unmanaged resources" such as open files or open connections. When an object with an unmanaged resource goes out of scope it will be garbage collected, but the garbage collector will not release those unmanaged resources. Those objects usually implement IDisposable which allows you to dispose of the resource before it is cleaned up.

For example, there is an unmanaged resource in the StreamWriter class, which opens a file and writes to it.

Here's an example of failing to release an unmanaged resource:

// This will write "hello1" to a file called "test.txt".
System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt");
sw1.WriteLine("hello1");

// This will throw a System.IO.IOException because "test.txt" is still locked by 
// the first StreamWriter.
System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt");
sw2.WriteLine("hello2");

To correctly release the file you must do the following:

// This will write "hello1" to a file called "test.txt" and then release "test.txt".
System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt");
sw1.WriteLine("hello1");
sw1.Dispose();

// This will write "hello2" to a file called "test.txt" and then release "test.txt".
System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt");
sw2.WriteLine("hello2");
sw2.Dispose();

Luckily, objects that implement IDisposable can be created in a using statement, then when it goes out of scope Dispose() will automatically be called on it. This is better than manually calling Dispose (like in the previous example) because if there were any unexpected exit points in the using block you can rest assured that your resource has been released.

using (System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt"))
{
  sw1.WriteLine("hello1");
}

using (System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt"))
{
  sw2.WriteLine("hello2");
}
Aaron T
  • 1,092
  • 2
  • 10
  • 25
  • what im asking is what would happen if i were to say: System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt"); sw1 = new System.IO.StreamWriter("anothertest.txt"); – shnk Sep 14 '18 at 03:39
  • If that were to happen, sw1 would reference the StreamWriter object that has "anothertest.txt" locked. The StreamWriter object that locked "test.txt" would have no references to it, "test.txt" would still be locked, and you would have no way to release it. – Aaron T Sep 14 '18 at 06:13
  • so i should be disposing it first then create a new reference and assign it to the resource? – shnk Sep 14 '18 at 14:57
  • Given your example, after you define sw1 and assign it the first StreamWriter you should call `sw1.Dispose()` before assigning sw1 to the second StreamWriter. – Aaron T Sep 14 '18 at 17:32