Пример #1
0
        public ResultDelegate <TSearch, TResult> CreateResultDelegate(LinkedList <CompositPropertyVertex> vertices,
                                                                      SearchStrategy <TSearch, TResult> strategy)
        {
            var delegateMap = new Dictionary <CompositPropertyVertex, ProxyDelegate <TSearch, TResult> >();

            var delegates = new ProxyDelegate <TSearch, TResult> [vertices.Count];

            var index = 0;

            vertices.ForEach(
                node =>
            {
                CreateDelegate(node.Value, delegateMap, strategy);
                delegates[index++] = delegateMap[node.Value];
            });

            var rootDelegate = new RootProxyDelegate <TSearch, TResult>(delegates, strategy);

            rootDelegate.BuildExecuteChildrenDelegate();

            return(rootDelegate.Execute);
        }
Пример #2
0
        private static void CreateDelegate(CompositPropertyVertex vertex,
                                           Dictionary <CompositPropertyVertex, ProxyDelegate <TSearch, TResult> > delegateMap,
                                           SearchStrategy <TSearch, TResult> strategy)
        {
            if (vertex.PropertyList.First == null)
            {
                throw new NullReferenceException();
            }

            if (delegateMap.ContainsKey(vertex))
            {
                return;
            }

            var propertyGetters = new Func <object, object> [vertex.PropertyList.Count];

            var parameter = Expression.Parameter(typeof(object), "obj");
            var nullConst = Expression.Constant(null);

            var hasCollection = false;

            var index = 0;

            vertex.PropertyList.ForEach(
                node =>
            {
                if (typeof(ICollection).IsAssignableFrom(node.Value.PropertyType))
                {
                    hasCollection = true;
                }

                var resultVariable = Expression.Variable(typeof(object), "result");

                var castVariable = Expression.Variable(node.Value.DeclaringType, "value");
                var castAs       = Expression.TypeAs(parameter, node.Value.DeclaringType);
                var castAssign   = Expression.Assign(castVariable, castAs);

                var checkNotNull = Expression.NotEqual(castVariable, nullConst);
                var memberAccess = Expression.Convert(Expression.MakeMemberAccess(castVariable, node.Value),
                                                      typeof(object));
                var conditionalMemberAccess = Expression.Condition(checkNotNull, memberAccess, nullConst);

                var resultAssign = Expression.Assign(resultVariable, conditionalMemberAccess);

                var returnTarget = Expression.Label(typeof(object));
                var returnLabel  = Expression.Label(returnTarget, nullConst);
                var returnExpr   = Expression.Return(returnTarget, resultVariable);

                var block = Expression.Block(typeof(object), new[] { castVariable, resultVariable }, castAssign,
                                             resultAssign, returnExpr, returnLabel);

                var deleg = Expression.Lambda <Func <object, object> >(block, parameter).Compile();

                propertyGetters[index++] = deleg;
            });

            var childDelegates = new ProxyDelegate <TSearch, TResult> [vertex.Children.Count];

            delegateMap[vertex] = new ProxyDelegate <TSearch, TResult>(propertyGetters, childDelegates, strategy,
                                                                       hasCollection);

            index = 0;
            vertex.Children.ForEach(
                node =>
            {
                CreateDelegate(node.Value, delegateMap, strategy);
                childDelegates[index++] = delegateMap[node.Value];
            });
        }