/// <summary> /// Generates a new hash code function. /// </summary> /// <param name="typeBuilder">The type builder to use.</param> /// <param name="fieldsToUse">All fields to use to compute the hash code.</param> /// <returns>The created hash code function.</returns> public static MethodInfo GenerateHashCode( this TypeBuilder typeBuilder, FieldInfo[] fieldsToUse) { var getHashCode = typeBuilder.DefineMethod( GetHashCodeInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual, typeof(int), Array.Empty <Type>()); var emitter = new ILEmitter(getHashCode.GetILGenerator()); var result = emitter.DeclareLocal(typeof(int)); emitter.EmitConstant(0); emitter.Emit(LocalOperation.Store, result); foreach (var field in fieldsToUse) { emitter.Emit(LocalOperation.Load, result); emitter.Emit(OpCodes.Ldarg_0); emitter.Emit(OpCodes.Ldflda, field); emitter.EmitCall(field.FieldType.GetMethod( GetHashCodeInfo.Name, BindingFlags.Public | BindingFlags.Instance)); emitter.Emit(OpCodes.Xor); emitter.Emit(LocalOperation.Store, result); } emitter.Emit(LocalOperation.Load, result); emitter.Emit(OpCodes.Ret); emitter.Finish(); typeBuilder.DefineMethodOverride(getHashCode, GetHashCodeInfo); return(getHashCode); }