예제 #1
0
        private protected override void InitializeByValue(PropertyInfo propertyInfo, XBindingFlags flags)
        {
            base.InitializeByValue(propertyInfo, flags);

            if ((flags & XBindingFlags.RWAutoPropertyDirectRW) != 0 /* || !VersionDifferences.IsSupportEmit */)
            {
                if (TypeHelper.IsAutoProperty(propertyInfo, out var fieldInfo) && fieldInfo != null)
                {
                    try
                    {
                        var offset = TypeHelper.OffsetOf(fieldInfo);

                        _get = (ref TStruct obj) => Underlying.AddByteOffset(ref Underlying.As <TStruct, TValue>(ref obj), offset);
                        _set = (ref TStruct obj, TValue value) => Underlying.AddByteOffset(ref Underlying.As <TStruct, TValue>(ref obj), offset) = value;

                        return;
                    }
                    catch
                    {
                    }
                }
            }

            if (_get is null)
            {
                var getMethod = propertyInfo.GetGetMethod((flags & XBindingFlags.NonPublic) != 0);

                if (getMethod != null)
                {
                    var __get = MethodHelper.CreateDelegate <GetValueHandler>(getMethod);

                    _get = VersionDifferences.IsSupportEmit ? __get : AOTCheck;

                    TValue AOTCheck(ref TStruct obj)
                    {
                        try
                        {
                            return(__get(ref obj));
                        }
                        catch (ExecutionEngineException)
                        {
                            __get = AOT;

                            return(AOT(ref obj));
                        }
                        finally
                        {
                            _get = __get;
                        }
                    }

                    TValue AOT(ref TStruct obj)
                    {
                        fixed(byte *ptr = &Underlying.As <TStruct, byte>(ref obj))
                        {
                            return((TValue)getMethod.Invoke(TypeHelper.CamouflageBox(ptr), null));
                        }
                    }
                }
            }

            if (_set is null)
            {
                var setMethod = propertyInfo.GetSetMethod((flags & XBindingFlags.NonPublic) != 0);

                if (setMethod != null)
                {
                    var __set = (SetValueHandler)Delegate.CreateDelegate(typeof(SetValueHandler), setMethod);

                    _set = VersionDifferences.IsSupportEmit ? __set : AOTCheck;

                    void AOTCheck(ref TStruct obj, TValue value)
                    {
                        try
                        {
                            __set(ref obj, value);
                        }
                        catch (ExecutionEngineException)
                        {
                            __set = AOT;

                            AOT(ref obj, value);
                        }
                        finally
                        {
                            _set = __set;
                        }
                    }

                    void AOT(ref TStruct obj, TValue value)
                    {
                        fixed(byte *ptr = &Underlying.As <TStruct, byte>(ref obj))
                        {
                            setMethod.Invoke(TypeHelper.CamouflageBox(ptr), new object[] { value });
                        }
                    }
                }
            }
        }