Ejemplo n.º 1
0
        private object GetTag([NotNull] Expression tagExpression)
        {
            if (tagExpression == null)
            {
                throw new ArgumentNullException(nameof(tagExpression));
            }
            switch (tagExpression)
            {
            case ConstantExpression constant:
                return(constant.Value);

            case UnaryExpression unary:
                if (unary.NodeType == ExpressionType.Convert)
                {
                    return(GetTag(unary.Operand));
                }
                break;
            }

            // ReSharper disable once ConstantNullCoalescingCondition
            var expression = Visit(tagExpression) ?? throw new BuildExpressionException($"Invalid tag expression {tagExpression}.", new InvalidOperationException());

            if (_buildContext.TryCompile(Expression.Lambda(expression.Convert(typeof(object)), true), out var tagFunc, out var error))
            {
                return(((Func <object>)tagFunc)());
            }

            throw error;
        }
        private object GetTag([NotNull] Expression tagExpression)
        {
            if (tagExpression == null)
            {
                throw new ArgumentNullException(nameof(tagExpression));
            }
            object tag;

            switch (tagExpression)
            {
            case ConstantExpression constant:
                tag = constant.Value;
                break;

            default:
                // ReSharper disable once ConstantNullCoalescingCondition
                var expression = Visit(tagExpression) ?? throw new BuildExpressionException($"Invalid tag expression {tagExpression}.", new InvalidOperationException());
                if (_buildContext.TryCompile(Expression.Lambda(expression, true), out var tagFunc, out var error))
                {
                    tag = ((Func <object>)tagFunc)();
                }
                else
                {
                    throw error;
                }

                break;
            }
Ejemplo n.º 3
0
            public bool TryBuildExpression(IBuildContext buildContext, ILifetime lifetime, out Expression expression, out Exception error)
            {
                var type        = buildContext.Key.Type.Descriptor();
                var keyComparer = buildContext.Key.Tag as IComparer <Key>;

                if (!type.IsConstructedGenericType())
                {
                    throw new BuildExpressionException($"Unsupported enumerable type {type}.", null);
                }

                var genericTypeArguments = type.GetGenericTypeArguments();

                if (genericTypeArguments.Length != 1)
                {
                    throw new BuildExpressionException($"Unsupported enumerable type {type}.", null);
                }

                var elementType = genericTypeArguments[0];
                var allKeys     = GetKeys(buildContext.Container, elementType);

                if (keyComparer != null)
                {
                    allKeys = allKeys.OrderBy(i => i, keyComparer);
                }
                var keys        = allKeys.ToArray();
                var positionVar = Expression.Variable(typeof(int));

                var conditionExpression =
                    keys.Length < 5
                        ? CreateConditions(buildContext, keys, elementType, positionVar)
                        : CreateSwitchCases(buildContext, keys, elementType, positionVar);

                if (buildContext.TryCompile(Expression.Lambda(conditionExpression, positionVar, buildContext.ContainerParameter, buildContext.ArgsParameter), out var factory, out error))
                {
                    var ctor = EnumerableTypeDescriptor.MakeGenericType(elementType).Descriptor().GetDeclaredConstructors().Single();
                    var enumerableExpression = Expression.New(ctor, Expression.Constant(factory), Expression.Constant(keys.Length), buildContext.ContainerParameter, buildContext.ArgsParameter);
                    expression = enumerableExpression;
                    return(true);
                }

                expression = default(Expression);
                return(false);
            }