Exemple #1
0
 private static void Cast(ILGenerator il, Type type, bool valueAsPointer)
 {
     if (type == typeof(object))
     {
     }
     else if (TypeHelpers._IsValueType(type))
     {
         if (valueAsPointer)
         {
             il.Emit(OpCodes.Unbox, type);
         }
         else
         {
             il.Emit(OpCodes.Unbox_Any, type);
         }
     }
     else
     {
         il.Emit(OpCodes.Castclass, type);
     }
 }
Exemple #2
0
        private static void WriteMapImpl(ILGenerator il, Type type, List <MemberInfo> members, FieldBuilder mapField,
                                         bool allowNonPublicAccessors, bool isGet)
        {
            OpCode obj, index, value;

            var fail = il.DefineLabel();

            if (mapField == null)
            {
                index = OpCodes.Ldarg_0;
                obj   = OpCodes.Ldarg_1;
                value = OpCodes.Ldarg_2;
            }
            else
            {
                il.DeclareLocal(typeof(int));
                index = OpCodes.Ldloc_0;
                obj   = OpCodes.Ldarg_1;
                value = OpCodes.Ldarg_3;

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, mapField);
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldloca_S, (byte)0);
                il.EmitCall(OpCodes.Callvirt, tryGetValue, null);
                il.Emit(OpCodes.Brfalse, fail);
            }
            var labels = new Label[members.Count];

            for (var i = 0; i < labels.Length; i++)
            {
                labels[i] = il.DefineLabel();
            }
            il.Emit(index);
            il.Emit(OpCodes.Switch, labels);
            il.MarkLabel(fail);
            il.Emit(OpCodes.Ldstr, "name");
            il.Emit(OpCodes.Newobj, typeof(ArgumentOutOfRangeException).GetConstructor(new[] { typeof(string) }));
            il.Emit(OpCodes.Throw);
            for (var i = 0; i < labels.Length; i++)
            {
                il.MarkLabel(labels[i]);
                var          member = members[i];
                var          isFail = true;
                FieldInfo    field;
                PropertyInfo prop;
                if ((field = member as FieldInfo) != null)
                {
                    il.Emit(obj);
                    Cast(il, type, true);
                    if (isGet)
                    {
                        il.Emit(OpCodes.Ldfld, field);
                        if (TypeHelpers._IsValueType(field.FieldType))
                        {
                            il.Emit(OpCodes.Box, field.FieldType);
                        }
                    }
                    else
                    {
                        il.Emit(value);
                        Cast(il, field.FieldType, false);
                        il.Emit(OpCodes.Stfld, field);
                    }
                    il.Emit(OpCodes.Ret);
                    isFail = false;
                }
                else if ((prop = member as PropertyInfo) != null)
                {
                    MethodInfo accessor;
                    if (prop.CanRead &&
                        (accessor =
                             isGet
                                ? prop.GetGetMethod(allowNonPublicAccessors)
                                : prop.GetSetMethod(allowNonPublicAccessors)) != null)
                    {
                        il.Emit(obj);
                        Cast(il, type, true);
                        if (isGet)
                        {
                            il.EmitCall(TypeHelpers._IsValueType(type) ? OpCodes.Call : OpCodes.Callvirt, accessor, null);
                            if (TypeHelpers._IsValueType(prop.PropertyType))
                            {
                                il.Emit(OpCodes.Box, prop.PropertyType);
                            }
                        }
                        else
                        {
                            il.Emit(value);
                            Cast(il, prop.PropertyType, false);
                            il.EmitCall(TypeHelpers._IsValueType(type) ? OpCodes.Call : OpCodes.Callvirt, accessor, null);
                        }
                        il.Emit(OpCodes.Ret);
                        isFail = false;
                    }
                }
                if (isFail)
                {
                    il.Emit(OpCodes.Br, fail);
                }
            }
        }
        private void Initialize()
        {
            if (_type == null || (current != null && current.GetType() != _type))
            {
                _type = current.GetType();
            }

            if (_typeMemberSelector != null)
            {
                _memberNames = _typeMemberSelector(_type);
            }

            var allMembers = _memberNames == null || _memberNames.Length == 0;

            accessor = TypeAccessor.Create(_type);
            if (accessor.GetMembersSupported)
            {
                var typeMembers = accessor.GetMembers();

                if (allMembers)
                {
                    _memberNames = new string[typeMembers.Count];
                    for (var i = 0; i < _memberNames.Length; i++)
                    {
                        _memberNames[i] = typeMembers[i].Name;
                    }
                }

                allowNull      = new BitArray(_memberNames.Length);
                effectiveTypes = new Type[_memberNames.Length];
                for (var i = 0; i < _memberNames.Length; i++)
                {
                    Type memberType = null;
                    var  iAllowNull = true;
                    var  hunt       = _memberNames[i];
                    foreach (var member in typeMembers)
                    {
                        if (member.Name == hunt)
                        {
                            if (memberType == null)
                            {
                                var tmp = member.Type;
                                memberType = Nullable.GetUnderlyingType(tmp) ?? tmp;

                                iAllowNull = !(TypeHelpers._IsValueType(memberType) && memberType == tmp);

                                // but keep checking, in case of duplicates
                            }
                            else
                            {
                                memberType = null; // duplicate found; say nothing
                                break;
                            }
                        }
                    }
                    allowNull[i]      = iAllowNull;
                    effectiveTypes[i] = memberType ?? typeof(object);
                }
            }
            else if (allMembers)
            {
                throw new InvalidOperationException(
                          "Member information is not available for this type; the required members must be specified explicitly");
            }

            //current = null;
            _isInitialized = true;
        }