L
Lasse Vågsæther Karlsen
Caddzooks said:Can someone spot the problem here:
public class Form1 : Form
{
public Form1()
{
using( MyLockObject lockobj = new MyLockObject() )
{
Application.Idle += delegate( object sender, EventArgs e )
{
lockobj.Kaboom();
};
}
}
}
Because the delegate assigned to the Idle event references an object (MyLockObject) that will already have been disposed when the event fires, it will be attempting to use a disposed object.
This itself isn't the problem, as I know that if I want to reference that object from code that runs after the fact, I can't dispose the object in the ctor.
The question is, why doesn't the compiler catch it, and help the programmer avoid a very hideous bug?
Well, in this particular case, the compiler would have to have lots of
assumptions about your code in order to warn you, and knowing these
assumptions might not be possible at all times.
Assumptions like:
- the Idle event is probably not going to be called in the constructor,
but much later (if you think about it, this is not an assumption about
the "Idle" event, but rather all events)
- the object is indeed unsafe to use after being Disposed (which is a
logical assumptions, but is no guarantee), in the manner it is used. For
instance, what if the method being called internally calls "IsDisposed"
and does nothing or something else that wouldn't crash in this case?
I don't think the C# compiler, without having a much more advanced
analysis engine, would be able to detect this reliable enough to warrant
this feature.
Resource tracking and proper usage is not easy. It's not *very* hard
either, but you need to know what you're doing, and in this case you're
yanking away the branch that the event is sitting on. The proper way
would be to unsubscribe the event before disposing of the object.
And I know what you asked, I'm just saying that I don't think it would
be possible to write a C# compiler that would detect all these nuances
and handle them with any guarantee as of the results.