Example #1
0
        private static Expression <TTo> ConvertImpl <TFrom, TTo>(Expression <TFrom> from)
            where TFrom : class
            where TTo : class
        {
            // figure out which types are different in the function-signature
            var fromTypes = from.Type.GetGenericArguments();
            var toTypes   = typeof(TTo).GetGenericArguments();

            if (fromTypes.Length != toTypes.Length)
            {
                throw new NotSupportedException("Incompatible lambda function-type signatures");
            }

            Dictionary <Type, Type> typeMap = new Dictionary <Type, Type>();

            for (int i = 0; i < fromTypes.Length; i++)
            {
                if (fromTypes[i] != toTypes[i])
                {
                    typeMap[fromTypes[i]] = toTypes[i];
                }
            }

            // re-map all parameters that involve different types
            Dictionary <Expression, Expression> parameterMap = new Dictionary <Expression, Expression>();

            ParameterExpression[] newParams = GenerateParameterMap(from, typeMap, parameterMap);

            // rebuild the lambda
            var body = new TypeConversionVisitor <TTo>(parameterMap).Visit(from.Body);

            return(Expression.Lambda <TTo>(body, newParams));
        }
        /// <summary>
        /// </summary>
        /// <typeparam name="From"></typeparam>
        /// <typeparam name="To"></typeparam>
        /// <param name="from"></param>
        /// <returns></returns>
        public virtual Expression <To> Convert <From, To>(Expression <From> from)
            where From : class
            where To : class
        {
            // Work out which types are different in the function-signature
            var fromTypes = from.Type.GetGenericArguments();
            var toTypes   = typeof(To).GetGenericArguments();

            if (fromTypes.Length != toTypes.Length)
            {
                throw new NotSupportedException("Incompatible lambda function-type signatures");
            }

            var typeMap = new Dictionary <Type, Type>();

            for (int i = 0; i < fromTypes.Length; i++)
            {
                if (fromTypes[i] != toTypes[i])
                {
                    typeMap[fromTypes[i]] = toTypes[i];
                }
            }

            // Re-map all parameters that involve different types
            var parameterMap = new Dictionary <Expression, Expression>();
            var newParams    = new ParameterExpression[from.Parameters.Count];

            for (int i = 0; i < newParams.Length; ++i)
            {
                Type newType;
                if (typeMap.TryGetValue(from.Parameters[i].Type, out newType))
                {
                    parameterMap[from.Parameters[i]] = newParams[i] =
                        Expression.Parameter(newType, from.Parameters[i].Name);
                }
                else
                {
                    newParams[i] = from.Parameters[i];
                }
            }

            // Rebuild the lambda
            var body = new TypeConversionVisitor(parameterMap).Visit(from.Body);
            var ret  = Expression.Lambda <To>(body, newParams);

            return(ret);
        }