/// <summary> /// Returns a hash code for this instance. /// </summary> /// <returns> /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// </returns> public override int GetHashCode() { unchecked { int hashCode = 17 + AllowNull.GetHashCode() ^ ReadOnly.GetHashCode() + 31 * GetHashCode(PossibleValues);; return((DefaultValue == null) ? hashCode : hashCode *32 ^ DefaultValue.GetHashCode()); } }
public Persist(Func <Type, MemberInfo, int> membersOrder = null, AllowNull allowNull = AllowNull.None) { Type = typeof(T); MembersOrder = membersOrder; AllowNull = allowNull; write = CreateWriteMethod().Compile(); read = CreateReadMethod().Compile(); }
public DataPersistSize(Type type, int charSize, AllowNull allowNull = AllowNull.None, Func <Type, MemberInfo, int> membersOrder = null) { Type = type; CharSize = charSize; AllowNull = allowNull; MembersOrder = membersOrder; getSize = CreateGetSizeMethod().Compile(); }
public DataPersist(Type type, Func <Type, MemberInfo, int> membersOrder = null, AllowNull allowNull = AllowNull.None) { Type = type; MembersOrder = membersOrder; AllowNull = allowNull; LambdaWrite = CreateWriteMethod(); write = LambdaWrite.Compile(); LambdaRead = CreateReadMethod(); read = LambdaRead.Compile(); }
private static bool CanBeNull(Type type, AllowNull allowNull, int depth) { //if (type == typeof(Guid)) // return false; if (type.IsEnum()) { return(false); } if (type.IsStruct() && !type.IsNullable()) { return(false); } if (allowNull == AllowNull.OnlyMembers) { return(depth > 0); } return(allowNull == AllowNull.All); }
public static Expression CreateReadBody(Expression reader, Type itemType, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull) { return(BuildRead(reader, itemType, membersOrder, allowNull, 0)); }
private static Expression BuildGetSizeWithAssignedOrCurrentVariable(Expression variable, int charSize, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull, int depth) { var type = variable.Type; if (DataType.IsPrimitiveType(type) && type.IsEnum() && type != typeof(Guid)) { return(BuildGetSize(variable, charSize, membersOrder, allowNull, depth + 1)); } ParameterExpression @var = Expression.Variable(type); return(Expression.Block(new ParameterExpression[] { @var }, Expression.Assign(@var, variable), Expression.Label(Expression.Label(typeof(int)), BuildGetSize(@var, charSize, membersOrder, allowNull, depth + 1)) )); }
public static Expression CreateReadBody(Expression reader, Type itemType, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull) { var item = Expression.Variable(itemType); List <Expression> list = new List <Expression>(); if (DataType.IsPrimitiveType(itemType) || itemType.IsEnum || itemType == typeof(Guid) || itemType.IsKeyValuePair() || itemType.IsArray || itemType.IsList() || itemType.IsDictionary() || itemType.IsNullable()) { return(BuildRead(reader, itemType, membersOrder, allowNull, true)); } else { list.Add(Expression.Assign(item, Expression.New(itemType))); foreach (var member in DataTypeUtils.GetPublicMembers(itemType, membersOrder)) { list.Add(Expression.Assign(Expression.PropertyOrField(item, member.Name), BuildRead(reader, member.GetPropertyOrFieldType(), membersOrder, allowNull, false))); } list.Add(Expression.Label(Expression.Label(itemType), item)); if (allowNull == AllowNull.All && !itemType.IsStruct()) { return(Expression.Condition(Expression.Call(reader, typeof(BinaryReader).GetMethod("ReadBoolean")), Expression.Block(itemType, new ParameterExpression[] { item }, list), Expression.Label(Expression.Label(itemType), Expression.Constant(null, item.Type)))); } } return(Expression.Block(itemType, new ParameterExpression[] { item }, list)); }
public DataPersistSize(Type type, AllowNull allowNull = AllowNull.None, Func <Type, MemberInfo, int> membersOrder = null) : this(type, 1, allowNull, membersOrder) { }
public bool IsNullable() { return(AllowNull.ToLower() == Nullable.ToLower() && TypeHelper.SqlServerType2CSharpType(DataType).ToLower() != String.ToLower()); }
public string this[AllowNull] string returnValue]
public string this[AllowNull] string allowNull, int? nullableInt, string optional = null]
private static Expression BuildGetSize(Expression item, int charSize, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull, int depth) { var type = item.Type; bool canBeNull = CanBeNull(type, allowNull, depth); if (type == typeof(Guid)) { return(GetPrimitiveValueSize(Expression.Call(item, type.GetMethod("ToByteArray")), charSize, false)); } if (type.IsEnum()) { return(GetPrimitiveValueSize(Expression.Convert(item, item.Type.GetEnumBaseType()), charSize, canBeNull)); } if (DataType.IsPrimitiveType(type)) { return(GetPrimitiveValueSize(item, charSize, canBeNull)); } if (type.IsKeyValuePair()) { var key = BuildGetSize(Expression.PropertyOrField(item, "Key"), charSize, membersOrder, allowNull, depth + 1); var value = BuildGetSize(Expression.PropertyOrField(item, "Value"), charSize, membersOrder, allowNull, depth + 1); return(Expression.Add(key, value)); } if (type.IsArray || type.IsList()) { var listSum = Expression.Variable(typeof(int)); var count = type.IsArray ? (Expression)Expression.ArrayLength(item) : Expression.Property(item, "Count"); var writeCount = Expression.Call(typeof(CountCompression).GetMethod("GetSize"), Expression.Convert(count, typeof(ulong))); int fixedSize = 0; var itemType = type.IsArray ? type.GetElementType() : type.GetGenericArgument(0); if (HasFixedSize(itemType, out fixedSize)) { if (!canBeNull) { return(Expression.Add(writeCount, Expression.Multiply(count, Expression.Constant(fixedSize)))); } return(Expression.Condition(Expression.NotEqual(item, Expression.Constant(null)), Expression.Add( Expression.Add(Expression.Constant(1), writeCount), Expression.Multiply(count, Expression.Constant(fixedSize))), Expression.Constant(1) )); } if (!canBeNull) { return(Expression.Block(new ParameterExpression[] { listSum }, Expression.Assign(listSum, writeCount), item.For(i => Expression.AddAssign(listSum, BuildGetSizeWithAssignedOrCurrentVariable(type.IsArray ? Expression.ArrayAccess(item, i) : item.This(i), charSize, membersOrder, allowNull, depth + 1)), Expression.Label()), Expression.Label(Expression.Label(typeof(int)), listSum) )); } return(Expression.Condition(Expression.NotEqual(item, Expression.Constant(null)), Expression.Block(new ParameterExpression[] { listSum }, Expression.Assign(listSum, Expression.Constant(1)), Expression.AddAssign(listSum, writeCount), item.For(i => Expression.AddAssign(listSum, BuildGetSizeWithAssignedOrCurrentVariable(type.IsArray ? Expression.ArrayAccess(item, i) : item.This(i), charSize, membersOrder, allowNull, depth + 1)), Expression.Label()), Expression.Label(Expression.Label(typeof(int)), listSum) ), Expression.Constant(1, typeof(int)) )); } if (type.IsDictionary()) { var keyType = type.GetGenericArgument(0); if (!IsSupportDictionaryKeyType(keyType)) { throw new NotSupportedException(String.Format("Dictionarty<{0}, TValue>", keyType.ToString())); } var valueType = type.GetGenericArgument(1); bool isEnum = type.GetGenericArgument(0).IsEnum(); if (!DataType.IsPrimitiveType(keyType) && !isEnum && type != typeof(Guid)) { throw new NotSupportedException(String.Format("Dictionarty<{0}, TValue>", type.GetGenericArgument(0).ToString())); } var dictSum = Expression.Variable(typeof(int)); var count = Expression.Property(item, "Count"); var writeCount = Expression.Call(typeof(CountCompression).GetMethod("GetSize"), Expression.Convert(count, typeof(ulong))); int keySize = 0; int valueSize = 0; if (HasFixedSize(keyType, out keySize) && HasFixedSize(valueType, out valueSize)) { if (!canBeNull) { return(Expression.Multiply(writeCount, Expression.Constant(keySize + valueSize))); } return(Expression.Condition(Expression.NotEqual(item, Expression.Constant(null)), Expression.Add( Expression.Constant(1), Expression.Multiply(writeCount, Expression.Constant(keySize + valueSize)) ), Expression.Constant(1) )); } if (!canBeNull) { return(Expression.Block(new ParameterExpression[] { dictSum }, Expression.Assign(dictSum, writeCount), item.ForEach(current => { var kv = Expression.Variable(current.Type); return Expression.Block(new ParameterExpression[] { kv }, Expression.Assign(kv, current), Expression.AddAssign(dictSum, BuildGetSizeWithAssignedOrCurrentVariable(Expression.PropertyOrField(kv, "Key"), charSize, membersOrder, allowNull, depth + 1)), Expression.AddAssign(dictSum, BuildGetSizeWithAssignedOrCurrentVariable(Expression.PropertyOrField(kv, "Value"), charSize, membersOrder, allowNull, depth + 1)) ); }, Expression.Label()), Expression.Label(Expression.Label(typeof(int)), dictSum) )); } return(Expression.Condition(Expression.NotEqual(item, Expression.Constant(null)), Expression.Block(new ParameterExpression[] { dictSum }, Expression.Assign(dictSum, Expression.Constant(1)), Expression.Assign(dictSum, writeCount), item.ForEach(current => { var kv = Expression.Variable(current.Type); return Expression.Block(new ParameterExpression[] { kv }, Expression.Assign(kv, current), Expression.AddAssign(dictSum, BuildGetSizeWithAssignedOrCurrentVariable(Expression.PropertyOrField(kv, "Key"), charSize, membersOrder, allowNull, depth + 1)), Expression.AddAssign(dictSum, BuildGetSizeWithAssignedOrCurrentVariable(Expression.PropertyOrField(kv, "Value"), charSize, membersOrder, allowNull, depth + 1)) ); }, Expression.Label()), Expression.Label(Expression.Label(typeof(int)), dictSum) ), Expression.Constant(1) )); } if (type.IsNullable()) { var getSize = BuildGetSize(Expression.PropertyOrField(item, "Value"), charSize, membersOrder, allowNull, depth + 1); if (!canBeNull) { return(getSize); } return(Expression.Condition(Expression.PropertyOrField(item, "HasValue"), Expression.Add(Expression.Constant(1), getSize), Expression.Constant(1) )); } if (type.IsClass() || type.IsStruct()) { List <ParameterExpression> variables = new List <ParameterExpression>(); List <Expression> list = new List <Expression>(); var members = DataTypeUtils.GetPublicMembers(type, membersOrder).ToList(); Expression megaAdd = Expression.Empty(); for (int i = 0; i < members.Count; i++) { var mType = members[i].GetUnderlyingType(); int mSize = 0; if (HasFixedSize(mType, out mSize)) { var getSize = BuildGetSize(Expression.PropertyOrField(item, members[i].Name), charSize, membersOrder, allowNull, depth + 1); megaAdd = (i == 0) ? getSize : Expression.Add(megaAdd, getSize); } else { var @var = Expression.Variable(members[i].GetUnderlyingType()); variables.Add(var); list.Add(Expression.Assign(var, Expression.PropertyOrField(item, members[i].Name))); var getSize = BuildGetSize(var, charSize, membersOrder, allowNull, depth + 1); megaAdd = (i == 0) ? getSize : Expression.Add(megaAdd, getSize); } } if (!canBeNull || type.IsStruct()) { if (list.Count == 0) { return(megaAdd); } list.Add(Expression.Label(Expression.Label(typeof(int)), megaAdd)); return(Expression.Block(variables, list)); } if (variables.Count == 0) { return(Expression.Block( Expression.Condition(Expression.NotEqual(item, Expression.Constant(null)), Expression.Add(Expression.Constant(1), megaAdd), Expression.Constant(1) ))); } list.Add(Expression.Label(Expression.Label(typeof(int)), Expression.Add(Expression.Constant(1), megaAdd))); return(Expression.Condition(Expression.NotEqual(item, Expression.Constant(null)), Expression.Block(variables, list), Expression.Constant(1) )); } throw new NotSupportedException(item.Type.ToString()); }
public static Expression CreateSizeBody(Expression item, int charSize, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull) { return(BuildGetSize(item, charSize, membersOrder, allowNull, 0)); }
public static Expression CreateWriteBody(Expression item, Expression writer, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull) { List <Expression> list = new List <Expression>(); if (DataType.IsPrimitiveType(item.Type) || item.Type.IsEnum || item.Type == typeof(Guid) || item.Type.IsKeyValuePair() || item.Type.IsArray || item.Type.IsList() || item.Type.IsDictionary() || item.Type.IsNullable()) { list.Add(BuildWrite(item, writer, membersOrder, allowNull, true)); } else { if (allowNull == AllowNull.All && !item.Type.IsStruct()) { list.Add(Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.Constant(true))); } foreach (var member in DataTypeUtils.GetPublicMembers(item.Type, membersOrder)) { list.Add(BuildWrite(Expression.PropertyOrField(item, member.Name), writer, membersOrder, allowNull, false)); } if (allowNull == AllowNull.All && !item.Type.IsStruct()) { return(Expression.IfThenElse(Expression.NotEqual(item, Expression.Constant(null, item.Type)), Expression.Block(list), Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.Constant(false)))); } } return(Expression.Block(list)); }
private static Expression BuildWrite(Expression item, Expression writer, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull, bool isTop) { var type = item.Type; bool canBeNull = allowNull == AllowNull.All || (allowNull == AllowNull.OnlyMembers && !isTop); if (type == typeof(Guid)) { return(GetWriteCommand(writer, Expression.Call(item, type.GetMethod("ToByteArray")), false)); } if (type.IsEnum) { return(GetWriteCommand(writer, Expression.Convert(item, item.Type.GetEnumUnderlyingType()), canBeNull)); } if (DataType.IsPrimitiveType(type)) { return(GetWriteCommand(writer, item, canBeNull)); } if (type.IsKeyValuePair()) { return(Expression.Block( BuildWrite(Expression.PropertyOrField(item, "Key"), writer, membersOrder, allowNull, false), BuildWrite(Expression.PropertyOrField(item, "Value"), writer, membersOrder, allowNull, false) )); } if (type.IsArray || type.IsList()) { if (!canBeNull) { return(Expression.Block(Expression.Call(typeof(CountCompression).GetMethod("Serialize"), writer, Expression.Convert(type.IsArray ? (Expression)Expression.ArrayLength(item) : Expression.Property(item, "Count"), typeof(ulong))), item.For(i => WriteAssignedOrCurrentVariable(type.IsArray ? Expression.ArrayAccess(item, i) : item.This(i), writer, membersOrder, allowNull), Expression.Label()))); } return(Expression.IfThenElse(Expression.NotEqual(item, Expression.Constant(null)), Expression.Block( Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.Constant(true)), Expression.Call(typeof(CountCompression).GetMethod("Serialize"), writer, Expression.Convert(type.IsArray ? (Expression)Expression.ArrayLength(item) : Expression.Property(item, "Count"), typeof(ulong))), item.For(i => WriteAssignedOrCurrentVariable(type.IsArray ? Expression.ArrayAccess(item, i) : item.This(i), writer, membersOrder, allowNull), Expression.Label())), Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.Constant(false)) )); } if (type.IsDictionary()) { if (!DataType.IsPrimitiveType(type.GetGenericArguments()[0]) && !type.GetGenericArguments()[0].IsEnum && type != typeof(Guid)) { throw new NotSupportedException(String.Format("Dictionarty<{0}, TValue>", type.GetGenericArguments()[0].ToString())); } if (!canBeNull) { return(Expression.Block( Expression.Call(typeof(CountCompression).GetMethod("Serialize"), writer, Expression.Convert(Expression.Property(item, "Count"), typeof(ulong))), item.ForEach(current => { var kv = Expression.Variable(current.Type); return Expression.Block(new ParameterExpression[] { kv }, Expression.Assign(kv, current), WriteAssignedOrCurrentVariable(Expression.PropertyOrField(kv, "Key"), writer, membersOrder, allowNull), WriteAssignedOrCurrentVariable(Expression.PropertyOrField(kv, "Value"), writer, membersOrder, allowNull) ); }, Expression.Label()) )); } return(Expression.IfThenElse(Expression.NotEqual(item, Expression.Constant(null)), Expression.Block( Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.Constant(true)), Expression.Call(typeof(CountCompression).GetMethod("Serialize"), writer, Expression.Convert(Expression.Property(item, "Count"), typeof(ulong))), item.ForEach(current => { var kv = Expression.Variable(current.Type); return Expression.Block(new ParameterExpression[] { kv }, Expression.Assign(kv, current), WriteAssignedOrCurrentVariable(Expression.PropertyOrField(kv, "Key"), writer, membersOrder, allowNull), WriteAssignedOrCurrentVariable(Expression.PropertyOrField(kv, "Value"), writer, membersOrder, allowNull) ); }, Expression.Label())), Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.Constant(false)) )); } if (type.IsNullable()) { if (!canBeNull) { return(BuildWrite(Expression.PropertyOrField(item, "Value"), writer, membersOrder, allowNull, false)); } return(Expression.Block(Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.PropertyOrField(item, "HasValue")), Expression.IfThen(Expression.PropertyOrField(item, "HasValue"), BuildWrite(Expression.PropertyOrField(item, "Value"), writer, membersOrder, allowNull, false)))); } if (type.IsClass || type.IsStruct()) { List <ParameterExpression> variables = new List <ParameterExpression>(); List <Expression> list = new List <Expression>(); if (canBeNull && !type.IsStruct()) { list.Add(Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.Constant(true))); } foreach (var member in DataTypeUtils.GetPublicMembers(type, membersOrder)) { if (DataType.IsPrimitiveType(type) || type.IsKeyValuePair()) { list.Add(BuildWrite(Expression.PropertyOrField(item, member.Name), writer, membersOrder, allowNull, false)); } else { var @var = Expression.Variable(member.GetPropertyOrFieldType()); variables.Add(var); list.Add(Expression.Assign(var, Expression.PropertyOrField(item, member.Name))); list.Add(BuildWrite(var, writer, membersOrder, allowNull, false)); } } if (!canBeNull || type.IsStruct()) { return(Expression.Block(variables, list)); } return(Expression.IfThenElse(Expression.NotEqual(item, Expression.Constant(null)), Expression.Block(variables, list), Expression.Call(writer, typeof(BinaryWriter).GetMethod("Write", new Type[] { typeof(bool) }), Expression.Constant(false)) )); } throw new NotSupportedException(item.Type.ToString()); }
public static Expression CreateWriteBody(Expression item, Expression writer, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull) { return(BuildWrite(item, writer, membersOrder, allowNull, 0)); }
private static Expression WriteAssignedOrCurrentVariable(Expression variable, Expression writer, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull) { var type = variable.Type; if (!DataType.IsPrimitiveType(type) && !type.IsEnum && type != typeof(Guid)) { ParameterExpression _var = Expression.Variable(type); return(Expression.Block(new ParameterExpression[] { _var }, Expression.Assign(_var, variable), BuildWrite(_var, writer, membersOrder, allowNull, false))); } return(BuildWrite(variable, writer, membersOrder, allowNull, false)); }
private static Expression BuildWriteAssignedOrCurrent(Expression item, Expression writer, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull, int depth) { var type = item.Type; if (type == typeof(Guid) || type.IsEnum() || DataType.IsPrimitiveType(type)) { return(BuildWrite(item, writer, membersOrder, allowNull, depth)); } ParameterExpression @var = Expression.Variable(type); return(Expression.Block(new ParameterExpression[] { @var }, Expression.Assign(@var, item), BuildWrite(@var, writer, membersOrder, allowNull, depth))); }
private static Expression BuildRead(Expression reader, Type itemType, Func <Type, MemberInfo, int> membersOrder, AllowNull allowNull, bool isTop) { bool canBeNull = allowNull == AllowNull.All || (allowNull == AllowNull.OnlyMembers && !isTop); if (itemType == typeof(Guid)) { return(Expression.New(itemType.GetConstructor(new Type[] { typeof(byte[]) }), GetReadCommand(reader, typeof(byte[]), false))); } if (itemType.IsEnum) { return(Expression.Convert(GetReadCommand(reader, itemType.GetEnumUnderlyingType(), canBeNull), itemType)); } if (DataType.IsPrimitiveType(itemType)) { return(GetReadCommand(reader, itemType, canBeNull)); } if (itemType.IsKeyValuePair()) { return(Expression.New( itemType.GetConstructor(new Type[] { itemType.GetGenericArguments()[0], itemType.GetGenericArguments()[1] }), BuildRead(reader, itemType.GetGenericArguments()[0], membersOrder, allowNull, false), BuildRead(reader, itemType.GetGenericArguments()[1], membersOrder, allowNull, false) )); } if (itemType.IsArray || itemType.IsList() || itemType.IsDictionary()) { var field = Expression.Variable(itemType); var lenght = Expression.Variable(typeof(int)); var block = Expression.Block( Expression.Assign(lenght, Expression.Convert(Expression.Call(typeof(CountCompression).GetMethod("Deserialize"), reader), typeof(int))), itemType.IsDictionary() && itemType.GetGenericArguments()[0] == typeof(byte[]) ? Expression.Assign(field, Expression.New(field.Type.GetConstructor(new Type[] { typeof(int), typeof(IEqualityComparer <byte[]>) }), lenght, Expression.Field(null, typeof(BigEndianByteArrayEqualityComparer), "Instance"))) : Expression.Assign(field, Expression.New(field.Type.GetConstructor(new Type[] { typeof(int) }), lenght)), field.For(i => { if (itemType.IsArray) { return(Expression.Assign(Expression.ArrayAccess(field, i), BuildRead(reader, itemType.GetElementType(), membersOrder, allowNull, false))); } else if (itemType.IsList()) { return(Expression.Call(field, field.Type.GetMethod("Add"), BuildRead(reader, itemType.GetGenericArguments()[0], membersOrder, allowNull, false))); } else //if (dataType.IsDictionary) { return(Expression.Call(field, field.Type.GetMethod("Add"), BuildRead(reader, itemType.GetGenericArguments()[0], membersOrder, allowNull, false), BuildRead(reader, itemType.GetGenericArguments()[1], membersOrder, allowNull, false) )); } }, Expression.Label(), lenght) ); if (canBeNull) { return(Expression.Block(field.Type, new ParameterExpression[] { field, lenght }, Expression.IfThenElse(Expression.Call(reader, typeof(BinaryReader).GetMethod("ReadBoolean")), block, Expression.Assign(field, Expression.Constant(null, field.Type))), Expression.Label(Expression.Label(field.Type), field))); } return(Expression.Block(field.Type, new ParameterExpression[] { field, lenght }, block, Expression.Label(Expression.Label(field.Type), field))); } if (itemType.IsNullable()) { if (!canBeNull) { return(Expression.New(itemType.GetConstructor(new Type[] { itemType.GetGenericArguments()[0] }), BuildRead(reader, itemType.GetGenericArguments()[0], membersOrder, allowNull, false))); } return(Expression.Condition(Expression.Call(reader, typeof(BinaryReader).GetMethod("ReadBoolean")), Expression.New(itemType.GetConstructor(new Type[] { itemType.GetGenericArguments()[0] }), BuildRead(reader, itemType.GetGenericArguments()[0], membersOrder, allowNull, false)), Expression.Constant(null, itemType))); } if (itemType.IsClass || itemType.IsStruct()) { var item = Expression.Variable(itemType); List <Expression> list = new List <Expression>(); list.Add(Expression.Assign(item, Expression.New(item.Type))); foreach (var member in DataTypeUtils.GetPublicMembers(itemType, membersOrder)) { list.Add(Expression.Assign(Expression.PropertyOrField(item, member.Name), BuildRead(reader, member.GetPropertyOrFieldType(), membersOrder, allowNull, false))); } if (!canBeNull || itemType.IsStruct()) { list.Add(Expression.Label(Expression.Label(item.Type), item)); return(Expression.Block(item.Type, new ParameterExpression[] { item }, list)); } return(Expression.Block(itemType, new ParameterExpression[] { item }, Expression.IfThenElse(Expression.Call(reader, typeof(BinaryReader).GetMethod("ReadBoolean")), Expression.Block(list), Expression.Assign(item, Expression.Constant(null, itemType))), Expression.Label(Expression.Label(item.Type), item))); } throw new ArgumentException(itemType.ToString()); }
public PersistSize(AllowNull allowNull = AllowNull.None, Func <Type, MemberInfo, int> membersOrder = null) : this(1, allowNull, membersOrder) { }