Sans me diriger vers MSDN, quelqu'un pourrait-il donner une explication concise et claire de l'objectif de chacun d'entre eux et quand les utiliser. (IntPtr, SafeHandle et HandleRef)
Réponses
Trop de publicités?IntPtr
est un simple entier struct que peut contenir un pointeur (ie., 32 bits sur les systèmes 32-bit, 64-bits sur les systèmes 64 bits).
SafeHandle
est une classe qui a pour but de tenir objet Win32 poignées - il a un finaliseur qui permet de s'assurer que la poignée est fermé lorsque l'objet est GC ed. SafeHandle
est une classe abstraite, parce que les différents Win32 poignées ont différentes façons dont ils ont besoin pour être fermé. Avant l'introduction de l' SafeHandle
, IntPtr
a été utilisée pour tenir Win32 poignées, mais de s'assurer qu'ils ont été correctement fermée et empêche la GC ed était de la responsabilité du programmeur.
HandleRef
est une façon de s'assurer que non géré poignée n'est pas GC ed lorsque vous êtes au milieu d'un appel de P/Invoke. Sans quelque chose comme HandleRef
, si votre code managé ne pas faire n'importe quoi avec la poignée après l'appel de P/Invoke, si les GC ont été exécutés au cours de l'appel de P/Invoke il ne se rende pas compte que le manche était encore en usage, et peut-GC. J'imagine (mais je ne suis pas sûr et je n'ai pas regardé) que SafeHandle
peut utiliser HandleRef
dans le cadre de sa gestion de la encapsulé poignée.
HWnd a = new HWnd();
B.SendMessage(a.Handle, ...);
En supposant que c'est la seule référence à "a" dans le programme, cela équivaut à:
HWnd a = new HWnd();
IntPtr h = a.Handle;
// a is no longer needed and thus can be GC'ed
B.SendMessage(h, ...);
Le problème est que lorsque "a" est éliminé, il ferme la poignée. Si cela se produit avant ou pendant l'appel à SendMessage, le handle sera invalide.
HandleRef empêche "a" d'être récupéré des ordures avant que le programme ne soit terminé avec h.