2

The SafeHandle constructor takes an invalidHandleValue. What is it used for if you have to implement IsInvalid anyway because it has no idea which member variable holds the pointer [I didn't know it implemented the handle member variable for you]?

mpen
  • 272,448
  • 266
  • 850
  • 1,236

2 Answers2

2

Looking at it in DotPeek, I see that it is used only to initialize the protected IntPtr handle member variable.

protected SafeHandle(IntPtr invalidHandleValue, bool ownsHandle)
{
  this.handle = invalidHandleValue;
  ...
}

I'd say that the logic for this is something like:

  • They want to guarantee that the handle member variable is initialized to something, so they make you pass the invalid value.
  • There might be additional logic you want to test for in IsInvalid, so they don't bother to provide a default implementation (which would require saving the passed invalidHandleValue in the ctor as well.)
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • Oh... I didn't even know there was a `this.handle` member that it was implementing for me. I guess I should be using that rather than my own :-) This makes a lot more sense now! – mpen Jul 15 '13 at 01:29
1

It is the default value of handle for when you call new SafeHandleDerivedClass() (the derived class may call base.SetHandle(someValue) in the constructor, but before that call the value will be whatever was passed in to the base class constructor).

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • I'm not sure how `SetHandleAsInvalid` *could* set `handle` back to that value, because it is never saved anywhere in the ctor. – Jonathon Reinhart Jul 15 '13 at 00:46
  • Did you look at the code in DotPeek for `SetHandleAsInvalid`? It is just a call out to native code, who knows if it is storing a value there outside of `this.handle`. The only two ways for it to work is either it intercepts any calls to `IsInvalid` and returns false on it's behalf or it sets `this.handle` to a known invalid value. – Scott Chamberlain Jul 15 '13 at 00:47
  • Right, but the constructor would have to have saved the `invalidHandleValue` that you passed (which it doesn't). I am very curious now though, how it is implemented. – Jonathon Reinhart Jul 15 '13 at 00:50
  • [MSDN](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.sethandleasinvalid.aspx): "Call the SetHandleAsInvalid method only when you know that your handle no longer references a resource. Doing so does not change the value of the handle field; it only marks the handle as closed. The handle might then contain a potentially stale value. The effect of this call is that no attempt is made to free the resources." – Jonathon Reinhart Jul 15 '13 at 00:52
  • Thanks for getting me to look into that though - I've never bothered much with the `SafeHandle` internals. – Jonathon Reinhart Jul 15 '13 at 00:59