/// <summary> /// Gets the reader with a specified generic method. /// </summary> private static PortableReflectiveReadAction GetReader(FieldInfo field, MethodInfo method, params Type[] genericArgs) { Debug.Assert(field != null); Debug.Assert(field.DeclaringType != null); // non-static if (genericArgs.Length == 0) { genericArgs = new[] { field.FieldType } } ; // Call IPortableReader method var readerParam = Expression.Parameter(typeof(IPortableReader)); var fldNameParam = Expression.Constant(PortableUtils.CleanFieldName(field.Name)); var readMethod = method.MakeGenericMethod(genericArgs); Expression readExpr = Expression.Call(readerParam, readMethod, fldNameParam); if (readMethod.ReturnType != field.FieldType) { readExpr = Expression.Convert(readExpr, field.FieldType); } // Assign field value var targetParam = Expression.Parameter(typeof(object)); var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); var assignExpr = Expression.Call(DelegateConverter.GetWriteFieldMethod(field), targetParamConverted, readExpr); // Compile and return return(Expression.Lambda <PortableReflectiveReadAction>(assignExpr, targetParam, readerParam).Compile()); } }
/// <summary> /// Gets the reader with a specified read action. /// </summary> private static PortableReflectiveReadAction GetReader <T>(FieldInfo field, Expression <Func <string, IPortableReader, T> > read) { Debug.Assert(field != null); Debug.Assert(field.DeclaringType != null); // non-static // Call IPortableReader method var readerParam = Expression.Parameter(typeof(IPortableReader)); var fldNameParam = Expression.Constant(PortableUtils.CleanFieldName(field.Name)); Expression readExpr = Expression.Invoke(read, fldNameParam, readerParam); if (typeof(T) != field.FieldType) { readExpr = Expression.Convert(readExpr, field.FieldType); } // Assign field value var targetParam = Expression.Parameter(typeof(object)); var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); var assignExpr = Expression.Call(DelegateConverter.GetWriteFieldMethod(field), targetParamConverted, readExpr); // Compile and return return(Expression.Lambda <PortableReflectiveReadAction>(assignExpr, targetParam, readerParam).Compile()); }
/// <summary> /// Gets the writer with a specified generic method. /// </summary> private static PortableReflectiveWriteAction GetWriter(FieldInfo field, MethodInfo method, params Type[] genericArgs) { Debug.Assert(field != null); Debug.Assert(field.DeclaringType != null); // non-static if (genericArgs.Length == 0) { genericArgs = new[] { field.FieldType } } ; // Get field value var targetParam = Expression.Parameter(typeof(object)); var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); var fldExpr = Expression.Field(targetParamConverted, field); // Call IPortableWriter method var writerParam = Expression.Parameter(typeof(IPortableWriter)); var fldNameParam = Expression.Constant(PortableUtils.CleanFieldName(field.Name)); var writeMethod = method.MakeGenericMethod(genericArgs); var writeExpr = Expression.Call(writerParam, writeMethod, fldNameParam, fldExpr); // Compile and return return(Expression.Lambda <PortableReflectiveWriteAction>(writeExpr, targetParam, writerParam).Compile()); }
/// <summary> /// Gets the reader with a specified write action. /// </summary> private static PortableReflectiveWriteAction GetWriter <T>(FieldInfo field, Expression <Action <string, IPortableWriter, T> > write, bool convertFieldValToObject = false) { Debug.Assert(field != null); Debug.Assert(field.DeclaringType != null); // non-static // Get field value var targetParam = Expression.Parameter(typeof(object)); var targetParamConverted = Expression.Convert(targetParam, field.DeclaringType); Expression fldExpr = Expression.Field(targetParamConverted, field); if (convertFieldValToObject) { fldExpr = Expression.Convert(fldExpr, typeof(object)); } // Call IPortableWriter method var writerParam = Expression.Parameter(typeof(IPortableWriter)); var fldNameParam = Expression.Constant(PortableUtils.CleanFieldName(field.Name)); var writeExpr = Expression.Invoke(write, fldNameParam, writerParam, fldExpr); // Compile and return return(Expression.Lambda <PortableReflectiveWriteAction>(writeExpr, targetParam, writerParam).Compile()); }
/// <summary> /// Compare two FieldInfo instances. /// </summary> private static int Compare(FieldInfo info1, FieldInfo info2) { string name1 = PortableUtils.CleanFieldName(info1.Name); string name2 = PortableUtils.CleanFieldName(info2.Name); return(string.Compare(name1, name2, StringComparison.OrdinalIgnoreCase)); }
/// <summary>Register type.</summary> /// <param name="type">Type.</param> /// <param name="typeId">Type ID.</param> /// <param name="converter">Name converter.</param> /// <param name="idMapper">ID mapper.</param> public void Register(Type type, int typeId, IPortableNameMapper converter, IPortableIdMapper idMapper) { if (type.GetInterface(typeof(IPortableMarshalAware).Name) != null) { return; } List <FieldInfo> fields = new List <FieldInfo>(); Type curType = type; while (curType != null) { foreach (FieldInfo field in curType.GetFields(Flags)) { if (!field.IsNotSerialized) { fields.Add(field); } } curType = curType.BaseType; } IDictionary <int, string> idMap = new Dictionary <int, string>(); foreach (FieldInfo field in fields) { string fieldName = PortableUtils.CleanFieldName(field.Name); int fieldId = PortableUtils.FieldId(typeId, fieldName, converter, idMapper); if (idMap.ContainsKey(fieldId)) { throw new PortableException("Conflicting field IDs [type=" + type.Name + ", field1=" + idMap[fieldId] + ", field2=" + fieldName + ", fieldId=" + fieldId + ']'); } idMap[fieldId] = fieldName; } fields.Sort(Compare); Descriptor desc = new Descriptor(fields); _types[type] = desc; }