Skip to content

Instantly share code, notes, and snippets.

@NickStrupat
Last active January 11, 2016 03:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NickStrupat/c31546b8ef9f25862511 to your computer and use it in GitHub Desktop.
Save NickStrupat/c31546b8ef9f25862511 to your computer and use it in GitHub Desktop.
StructReferenceEquals
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
public static class Struct {
public static Boolean ReferenceEquals<T>(ref T a, ref T b) where T : struct => Cache<T>.Func(ref a, ref b);
private static class Cache<T> where T : struct {
public delegate Boolean ReferenceEqualsDelegate(ref T a, ref T b);
public static readonly ReferenceEqualsDelegate Func = GetReferenceEquals();
private static ReferenceEqualsDelegate GetReferenceEquals() {
var invokeMethodInfo = typeof(ReferenceEqualsDelegate).GetMethod(nameof(Action.Invoke));
var returnType = invokeMethodInfo.ReturnType;
var parameterTypes = invokeMethodInfo.GetParameters().Select(x => x.ParameterType).ToArray();
var dynamicMethod = new DynamicMethod($"{nameof(ReferenceEquals)}_{typeof(T).Name}", returnType, parameterTypes, restrictedSkipVisibility: true);
var ilGenerator = dynamicMethod.GetILGenerator();
var typedReferenceValueFieldInfo = typeof(TypedReference).GetField("Value", BindingFlags.NonPublic | BindingFlags.Instance);
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Mkrefany, typeof(T));
ilGenerator.Emit(OpCodes.Ldfld, typedReferenceValueFieldInfo);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Mkrefany, typeof(T));
ilGenerator.Emit(OpCodes.Ldfld, typedReferenceValueFieldInfo);
ilGenerator.Emit(OpCodes.Call, typeof(IntPtr).GetMethod("op_Equality", new [] { typeof(IntPtr), typeof(IntPtr) }));
ilGenerator.Emit(OpCodes.Ret);
return (ReferenceEqualsDelegate) dynamicMethod.CreateDelegate(typeof(ReferenceEqualsDelegate));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment