in src/Epam.GraphQL/Extensions/TypeBuilderExtensions.cs [277:328]
public static void DefineGetHashCodeByPublicPropertiesMethod(this TypeBuilder typeBuilder, IEnumerable<PropertyInfo> properties)
{
var getHasCodeMethodInfo = _getHashCodeMethodsInfo.GetOrAdd(
typeBuilder.GetBaseType(),
baseType => baseType.GetMethod(
nameof(object.GetHashCode),
BindingFlags.Public | BindingFlags.Instance,
null,
Type.EmptyTypes,
null));
var getHashCode = typeBuilder.DefineMethod(
nameof(object.GetHashCode),
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
typeof(int),
Type.EmptyTypes);
typeBuilder.DefineMethodOverride(getHashCode, getHasCodeMethodInfo);
var il = getHashCode.GetILGenerator();
il
.DeclareLocal<HashCode>()
.DeclareLocal<int>()
.Ldloca(0)
.Initobj<HashCode>();
foreach (var property in properties)
{
var comparer = typeof(EqualityComparer<>).MakeGenericType(property.PropertyType);
var getMethodInfo = property.GetGetMethod();
var addMethod = _hashCodeAddMethodsInfo.GetOrAdd(property.PropertyType, type =>
{
_hashCodeAddMethodInfo ??= ReflectionHelpers.GetMethodInfo<object>(default(HashCode).Add<object>);
return _hashCodeAddMethodInfo.MakeGenericMethod(property.PropertyType);
});
il
.Ldloca(0)
.Ldarg(0)
.Call(getMethodInfo)
.Call(addMethod);
}
il
.Ldloca(0)
.Call(_hashCodeToHashCodeMethodInfo)
.Stloc(1)
.Ldloc(1)
.Ret();
}