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); } }
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; }