I’m stuck with .Net 1.1 application (i.e. I can not use the generics goodies from 2.0 for now), and I was trying to optimize some parts of the code. As it deals a lot with runtime callable wrappers, which need to be released, I ended up to create a utility method which loops until all references are released. The signature of the method is:
void ReleaseObject(object comObject)
After releasing all comObjects, I call GC.Collect and GC.WaitForPendingFinalizers (don’t ask – anybody dealing with Office interop knows).
And … as usual, I hit a corner case – if I do not assign the corresponding managed reference to null before the GC.Collect call, it does not cleanup properly.
So, my code looks like:
ReleaseObject(myComObject); myComObject = null; GC.Collect() ...
As, there are a bunch of xxx=null, I decided to put this in the util method, but as there is a difference between passing by reference, and passing a reference parameter, obviously I had to change the method to:
void ReleaseObject(out object comObject) { //do release comObject = null; }
and edit the caller to:
MyComClass myComObject = xxxx; ReleaseObject(out myComObject);
This fails with a message: ‘Cannot convert from ‘out MyComClass’ to ‘out object”
While I can think of why it can be a problem (i.e. the reverse cast from object to MyComClass is not implicit, and there is no guarantee what the method will do), I was wondering if there is a workaround, or I need to stay with my hundreds assignments of nulls.
Note: I have a bunch of different COM objects types, thats why I need a ‘object’ parameter, and not a type safe one.
Why is it better to call a method than to just set the variable to null? They’re both single line calls, and the latter is a lot simpler.
It does sound very odd that you need to set them to null in the first place though. Are these static variables, or instance variables whose values need to be released earlier than their containing object? If the variable is just a local variable which will go out of scope anyway, setting it to null shouldn’t make any difference (in release).
Do the RCWs not implement IDisposable? If so, calling Dispose (preferably via a using statement) would be the best bet.
(After discussions in comments.)
These are local variables, which aren’t referenced later in the method. That means the garbage collector will realise that they don’t need to be treated as ‘root’ references – so setting them to null shouldn’t make any difference.
To answer the original question directly, however: no, you can’t pass a variable by reference unless the method parameter is of exactly the same type, so you’re out of luck here. (With generics it would be possible, but you’ve said you’re limited to .NET 1.1.)