Vous pouvez en fait juste utiliser l' Unsafe.AreSame
méthode à partir du Système.Moment de l'exécution.CompilerServices.Dangereuses en colis.
Cela permettra de comparer les références directement et est le plus propre solution. La méthode est écrite dans IL et compare simplement les références, parce que, eh bien... vous pouvez le faire en IL :)
Si vous voulez comparer les deux références de différents types, vous pouvez lancer l'un d'entre eux à l'aide de cette surcharge de Unsafe.As
:
static bool AreSame<T1, T2>(ref T1 a, ref T2 b)
=> Unsafe.AreSame(ref Unsafe.As<T1, T2>(ref a), ref b);
Voici une autre suggestion si la coulée de référence se sent maladroit: utiliser mon InlineIL.Fody de la bibliothèque qui vous permet d'injecter arbitraire de code IL directement dans votre code C#:
static bool AreSame<T1, T2>(ref T1 a, ref T2 b)
{
IL.Emit.Ldarg(nameof(a));
IL.Emit.Ldarg(nameof(b));
IL.Emit.Ceq();
return IL.Return<bool>();
}
Je dis cela, car il est plus facile que émettant code au moment de l'exécution avec la Réflexion.Émettre, parce que vous ne pouvez pas créer un générique DynamicMethod
et vous avez besoin de générer une dynamique de type. Vous pouvez également écrire un IL du projet, mais il se sent aussi exagéré juste pour une méthode.
Aussi, vous éviter de prendre une dépendance sur une bibliothèque externe, si c'est important pour vous.
Note que je ne serais pas totalement confiance à l' __makeref
et Unsafe.AsPointer
solutions en raison de la possibilité d'une condition de concurrence: si vous êtes assez malheureux pour obtenir ces conditions:
- les deux références sont égaux
- la GC est déclenchée par un autre thread après le premier côté de la comparaison est évalué mais avant que l'autre est
- vos points de référence quelque part pour le tas managé
- l'objet référencé est déplacé par le GC pour des tas de compactage des fins de
Ainsi, alors que le pointeur qui a déjà été évalués ne seront pas mis à jour par le conseil d'administration avant la comparaison, de sorte que vous obtiendrez un résultat incorrect.
Est-il susceptible de se produire? Pas vraiment. Mais il pourrait.
L' Unsafe.AreSame
méthode fonctionne toujours en byref de l'espace, de sorte que le GC peut suivre et mettre à jour les références à tout moment.