Exemple #1
0
        private static IEqualityComparer <T> KeyValuePairEqualityComparer <T>(Type type)
        {
            var l = Expression.Parameter(type, "l");
            var r = Expression.Parameter(type, "r");

            var keyL = Expression.Property(l, "Key");
            var keyR = Expression.Property(r, "Key");

            var valueL = Expression.Property(l, "Value");
            var valueR = Expression.Property(r, "Value");

            var keyComparer   = ExistingEqualityComparer(keyL.Type);
            var valueComparer = ExistingEqualityComparer(valueL.Type);

            var keysEqual   = Expression.Call(keyComparer.Item1, keyComparer.Item2, keyL, keyR);
            var valuesEqual = Expression.Call(valueComparer.Item1, valueComparer.Item2, valueL, valueR);

            var equals = Expression.And(keysEqual, valuesEqual);

            var hashCodeKey   = Expression.Call(keyComparer.Item1, keyComparer.Item3, keyL);
            var hashCodeValue = Expression.Call(valueComparer.Item1, valueComparer.Item3, valueL);

            var hashCode = HashCodeSeed();
            var hashCodeStepMultiplier = HashCodeStepMultiplier();

            hashCode = BinaryExpression.Add(hashCodeKey, BinaryExpression.Multiply(hashCode, hashCodeStepMultiplier));
            hashCode = BinaryExpression.Add(hashCodeValue, BinaryExpression.Multiply(hashCode, hashCodeStepMultiplier));

            return(new FuncEqualityComparer <T>(
                       Expression.Lambda <DelegateFunc <T, T, bool> >(equals, l, r).Compile(),
                       Expression.Lambda <DelegateFunc <T, int> >(hashCode, l).Compile()));
        }
Exemple #2
0
        public static Expression DefaultMergeFunction <T>()
            where T : struct, IComparable
        {
            ParameterExpression val1Expr = Expression.Parameter(typeof(T), "oldvalue");
            ParameterExpression val2Expr = Expression.Parameter(typeof(T), "newvalue");
            BinaryExpression    addExpr  = BinaryExpression.Add(val1Expr, val2Expr);

            var lambdaExpr =
                Expression.Lambda <Func <T, T, T> >(
                    addExpr, new ParameterExpression[] { val1Expr, val2Expr });

            return(lambdaExpr);
        }
Exemple #3
0
        static void Main(string[] args)
        {
            Console.WriteLine("Start TestLinqExpression");
            Func <int> f1  = () => 2 + 2;
            int        res = f1();

            Console.WriteLine(res);

            // Теперь повторим это через Expression (заменим слагаемые)
            Expression exp = BinaryExpression.Add(ConstantExpression.Constant(4), ConstantExpression.Constant(4));
            var        f2  = Expression.Lambda <Func <int> >(exp).Compile();

            res = f2();
            Console.WriteLine(res);

            // Теперь придумываем "язык" для формул exp. Язык будет объектным. Константа c целого типа будет
            // соответствовать выражению ConstantExpression.Constant(c), массив object[] {"Add", object1, object2}
            // будет BinaryExpression.Add(object1,  object2)
            // Делаем транслятор object -> Expression

            Func <object, Expression> objectTranslator = null;

            objectTranslator = (object ob) =>
            {
                if (ob is int)
                {
                    return(ConstantExpression.Constant(ob));
                }
                return(null);
            };

            // испытываем
            Expression expr2 = objectTranslator(444);

            Console.WriteLine(Expression.Lambda <Func <int> >(expr2).Compile()());

            // Делаем другую ветвь в трансляторе
            objectTranslator = (object ob) =>
            {
                if (ob is int)
                {
                    return(ConstantExpression.Constant(ob));
                }
                if (ob is object[])
                {
                    object[] arr = (object[])ob;
                    if ((string)arr[0] == "Add")
                    {
                        return(BinaryExpression.Add(objectTranslator(arr[1]), objectTranslator(arr[1])));
                    }
                }
                return(null);
            };

            // испытываем
            object[] myexpression = new object[] { "Add", 2222, 4444 }; // Вот он язык описания вычислений!!!

            Expression expr3 = objectTranslator(myexpression);

            Console.WriteLine(Expression.Lambda <Func <int> >(expr3).Compile()());

            myexpression = new object[] { "Add", new object[] { "Add", 2, 2 }, new object[] { "Add", 2, 2 } };
            Console.WriteLine(Expression.Lambda <Func <int> >(objectTranslator(myexpression)).Compile()());
        }
Exemple #4
0
 private static Expression GenerateStringConcat(Expression left, Expression right)
 {
     return(BinaryExpression.Add(left, right, typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) })));
 }