private static AccessTools.FieldRef <F>?StaticFieldRefAccessInternal <F>(FieldInfo fieldInfo)
        {
            if (!Helper.IsValid())
            {
                return(null);
            }

            if (!fieldInfo.IsStatic)
            {
                Trace.TraceError($"AccessTools2.StaticFieldRefAccessInternal<{typeof(F).FullName}>: Field must be static");
                return(null);
            }

            if (!ValidateFieldType <F>(fieldInfo))
            {
                return(null);
            }

            var dm = DynamicMethodDefinitionHandle.Create(
                $"__refget_{fieldInfo.DeclaringType?.Name ?? "null"}_static_fi_{fieldInfo.Name}", typeof(F).MakeByRefType(), new Type[0]);

            if (dm?.GetILGenerator() is not {
            } il)
            {
                return(null);
            }

            il.Emit(OpCodes.Ldsflda, fieldInfo);
            il.Emit(OpCodes.Ret);

            //return dm?.Generate() is { } methodInfo ? GetDelegate<AccessTools.FieldRef<F>>(methodInfo) : null;
            return(dm?.Generate()?.CreateDelegate(typeof(AccessTools.FieldRef <F>)) as AccessTools.FieldRef <F>);
        }
        private static AccessTools.StructFieldRef <T, F>?StructFieldRefAccessInternal <T, F>(FieldInfo fieldInfo) where T : struct
        {
            if (!ValidateFieldType <F>(fieldInfo))
            {
                return(null);
            }

            var dm = DynamicMethodDefinitionHandle.Create(
                $"__refget_{typeof(T).Name}_struct_fi_{fieldInfo.Name}", typeof(F).MakeByRefType(), new[] {
                typeof(T).MakeByRefType()
            });

            if (dm?.GetILGenerator() is not {
            } il)
            {
                return(null);
            }

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldflda, fieldInfo);
            il.Emit(OpCodes.Ret);

            //return dm?.Generate() is { } methodInfo ? GetDelegate<AccessTools.StructFieldRef<T, F>>(methodInfo) : null;
            return(dm?.Generate()?.CreateDelegate(typeof(AccessTools.StructFieldRef <T, F>)) as AccessTools.StructFieldRef <T, F>);
        }
        private static AccessTools.FieldRef <T, F>?FieldRefAccessInternal <T, F>(FieldInfo fieldInfo, bool needCastclass) where T : class
        {
            if (!Helper.IsValid())
            {
                return(null);
            }

            if (fieldInfo.IsStatic)
            {
                Trace.TraceError($"AccessTools2.FieldRefAccessInternal<{typeof(T).FullName}, {typeof(F).FullName}>: Field must not be static");
                return(null);
            }

            if (!ValidateFieldType <F>(fieldInfo))
            {
                return(null);
            }

            var delegateInstanceType = typeof(T);
            var declaringType        = fieldInfo.DeclaringType;

            var dm = DynamicMethodDefinitionHandle.Create(
                $"__refget_{delegateInstanceType.Name}_fi_{fieldInfo.Name}", typeof(F).MakeByRefType(), new[] {
                delegateInstanceType
            });

            if (dm?.GetILGenerator() is not {
            } il)
            {
                return(null);
            }

            il.Emit(OpCodes.Ldarg_0);
            // The castclass is needed when T is a parent class or interface of declaring type (e.g. if T is object),
            // since there's no guarantee the instance passed to the delegate is actually of the declaring type.
            // In such a situation, the castclass will throw an InvalidCastException and thus prevent undefined behavior.
            if (needCastclass)
            {
                il.Emit(OpCodes.Castclass, declaringType);
            }
            il.Emit(OpCodes.Ldflda, fieldInfo);
            il.Emit(OpCodes.Ret);

            //return dm?.Generate() is { } methodInfo ? GetDelegate<AccessTools.FieldRef<T, F>>(methodInfo) : null;
            return(dm?.Generate()?.CreateDelegate(typeof(AccessTools.FieldRef <T, F>)) as AccessTools.FieldRef <T, F>);
        }