I had copied the Shader class without initially thinking about it much. Today I was basically rewriting it and noticed the disposal logic, much of which originated with the tutorial code. This is a bit nitpicky, but the discussion of unmanaged resource cleanup in the 1.2 Hello Triangle chapter at the end of the Compiling the Shaders section may warrant reconsideration.
.NET finalizers aren't remotely equivalent to C++ destructors, so it doesn't make sense to state, "We can't do it in the finalizer due to the Object-Oriented Language Problem." Nobody should be contemplating resource cleanup in the finalizer as correct behavior in the first place, completely irrespective of whether or not it's problematic for OpenGL specifically.
The code, of course, is meant to output a warning if disposal wasn't correctly called but (a) that's detrimental to performance because declaring a finalizer adds it to .NET's finalizer tracking queue, (b) there's no guarantee about when a finalizer might be invoked, or whether it will be invoked at all, ever, and (c) in practice they are never invoked when the application is exiting, which is the most likely scenario here. So in short, while a warning message looks like a good idea, in reality it'll never actually be seen. It's wasted effort.
I'd say it makes the most sense just to show a Dispose method. Also, I suppose the sample code was cut-and-pasted from somewhere else since arguments like bool disposing aren't even used (that's an arguably-bad design when you want to know whether or not Dispose is being called from the finalizer.) Even though the class shouldn't have a finalizer, it should still call SuppressFinalize in case a derived class does declare a finalizer.
Just keep it simple:
private bool IsDisposed = false;
public virtual void Dispose()
{
if (IsDisposed) return;
GL.DeleteProgram(Handle);
IsDisposed = true;
GC.SuppressFinalize(this);
}
Like I said, nitpicky.
I had copied the
Shaderclass without initially thinking about it much. Today I was basically rewriting it and noticed the disposal logic, much of which originated with the tutorial code. This is a bit nitpicky, but the discussion of unmanaged resource cleanup in the 1.2 Hello Triangle chapter at the end of the Compiling the Shaders section may warrant reconsideration..NET finalizers aren't remotely equivalent to C++ destructors, so it doesn't make sense to state, "We can't do it in the finalizer due to the Object-Oriented Language Problem." Nobody should be contemplating resource cleanup in the finalizer as correct behavior in the first place, completely irrespective of whether or not it's problematic for OpenGL specifically.
The code, of course, is meant to output a warning if disposal wasn't correctly called but (a) that's detrimental to performance because declaring a finalizer adds it to .NET's finalizer tracking queue, (b) there's no guarantee about when a finalizer might be invoked, or whether it will be invoked at all, ever, and (c) in practice they are never invoked when the application is exiting, which is the most likely scenario here. So in short, while a warning message looks like a good idea, in reality it'll never actually be seen. It's wasted effort.
I'd say it makes the most sense just to show a
Disposemethod. Also, I suppose the sample code was cut-and-pasted from somewhere else since arguments likebool disposingaren't even used (that's an arguably-bad design when you want to know whether or notDisposeis being called from the finalizer.) Even though the class shouldn't have a finalizer, it should still callSuppressFinalizein case a derived class does declare a finalizer.Just keep it simple:
Like I said, nitpicky.