示例#1
0
        private Func <String, TRecord> CreateLineParser()
        {
            ParameterExpression lineExpression = Expression.Parameter(typeof(String), "line");

            ParameterExpression returnExpression  = Expression.Variable(typeof(TRecord), "ret");
            ParameterExpression stringsExpression = Expression.Variable(typeof(String[]), "strings");

            List <Expression> expressions =
                new List <Expression> {
                Expression.Assign(returnExpression, Expression.New(typeof(TRecord)))
            };


            // Create expression to split string
            DelimitedRecordAttribute delimitedRecordAttribute = (DelimitedRecordAttribute)_recordAttribute;

            Expression seperatorArray = Expression.NewArrayInit(typeof(String), Expression.Constant(delimitedRecordAttribute.Delimiter));

            expressions.Add(Expression.Assign(stringsExpression, Expression.Call(lineExpression, typeof(String).GetMethod("Split", new Type[] { typeof(String[]), typeof(StringSplitOptions) }), seperatorArray, Expression.Constant(StringSplitOptions.None))));

            int i = 0;

            foreach (PropertyInfo propertyInfo in typeof(TRecord).GetProperties())
            {
                DelimitedFieldAttribute delimitedFieldAttribute = propertyInfo.GetCustomAttribute <DelimitedFieldAttribute>(false);

                if (delimitedFieldAttribute == null)
                {
                    // If a property does not have a DelimitedFieldAttribute then we can simply skip it.
                    break;
                }

                expressions.AddRange(CreateFieldExpression(propertyInfo, delimitedFieldAttribute, returnExpression, Expression.ArrayIndex(stringsExpression, Expression.Constant(i))));

                i++;
            }

            expressions.Add(returnExpression);

            Expression body = Expression.Block(new List <ParameterExpression> {
                returnExpression, stringsExpression
            }, expressions);

            LambdaExpression lambda = Expression.Lambda <Func <String, TRecord> >(body, lineExpression);

            return((Func <String, TRecord>)lambda.Compile());
        }
示例#2
0
        private static Func <String, TRecord> CreateLineParser(IRecordAttribute attribute)
        {
            ParameterExpression lineExpression = Expression.Parameter(typeof(String), "line");

            ParameterExpression returnExpression  = Expression.Variable(typeof(TRecord), "ret");
            ParameterExpression stringsExpression = Expression.Variable(typeof(String[]), "strings");

            List <Expression> expressions =
                new List <Expression> {
                Expression.Assign(returnExpression, Expression.New(typeof(TRecord)))
            };

            if (attribute.GetType() == typeof(DelimitedRecordAttribute))
            {
                DelimitedRecordAttribute delimitedRecordAttribute = (DelimitedRecordAttribute)attribute;

                Expression seperatorArray = Expression.NewArrayInit(typeof(String), Expression.Constant(delimitedRecordAttribute.Delimiter));
                expressions.Add(Expression.Assign(stringsExpression, Expression.Call(lineExpression, typeof(String).GetMethod("Split", new[] { typeof(String[]), typeof(StringSplitOptions) }), seperatorArray, Expression.Constant(StringSplitOptions.None))));
            }

            int i = 0;

            foreach (PropertyInfo propertyInfo in typeof(TRecord).GetProperties())
            {
                DelimitedFieldAttribute  delimitedFieldAttribute  = propertyInfo.GetCustomAttribute <DelimitedFieldAttribute>(false);
                FixedWidthFieldAttribute fixedWidthFieldAttribute = propertyInfo.GetCustomAttribute <FixedWidthFieldAttribute>(false);

                if (delimitedFieldAttribute == null && fixedWidthFieldAttribute == null)
                {
                    // If property has no derivative of FieldAttribute then we do not include it in parsing.
                    break;
                }
                else if (delimitedFieldAttribute != null && attribute.GetType() != typeof(DelimitedRecordAttribute))
                {
                    throw new Exception($"{propertyInfo.Name} cannot have a DelimitedField attribute.");
                }
                else if (fixedWidthFieldAttribute != null && attribute.GetType() != typeof(FixedWidthRecordAttribute))
                {
                    throw new Exception($"{propertyInfo.Name} cannot have a FixedWidthField attribute.");
                }

                if (delimitedFieldAttribute != null)
                {
                    //If we are missing delimiters then we assume that it is missing.
                    Expression valueExpression = Expression.Condition(Expression.GreaterThan(Expression.ArrayLength(stringsExpression), Expression.Constant(i)), Expression.ArrayIndex(stringsExpression, Expression.Constant(i)), Expression.Constant(""));
                    expressions.AddRange(CreateFieldExpression(propertyInfo, delimitedFieldAttribute, returnExpression, valueExpression));

                    i++;
                }
                else
                {
                    Expression substring = Expression.Call(lineExpression, typeof(string).GetMethod("Substring", new[] { typeof(int), typeof(int) }) ?? throw new InvalidOperationException(), Expression.Constant(i), Expression.Constant(fixedWidthFieldAttribute.FieldSize));
                    expressions.AddRange(CreateFieldExpression(propertyInfo, fixedWidthFieldAttribute, returnExpression, substring));

                    i += fixedWidthFieldAttribute.FieldSize;
                }
            }

            expressions.Add(returnExpression);

            Expression body = Expression.Block(new List <ParameterExpression> {
                returnExpression, stringsExpression
            }, expressions);

            LambdaExpression lambda = Expression.Lambda <Func <String, TRecord> >(body, lineExpression);

            return((Func <String, TRecord>)lambda.Compile());
        }