diff --git a/Build/ExpressionReflect.nuspec b/Build/ExpressionReflect.nuspec
index 2921c76..7fad4ff 100644
--- a/Build/ExpressionReflect.nuspec
+++ b/Build/ExpressionReflect.nuspec
@@ -22,8 +22,8 @@
-
-
-
+
+
+
diff --git a/README.md b/README.md
index 9b9410c..b67532c 100644
--- a/README.md
+++ b/README.md
@@ -5,10 +5,10 @@ Why?
----
Provides the ability to "compile" expressions to delegates without using Reflection.Emit but only using reflection.
-The created delegate will make use of reflection to execute the expression when it is invoked. This is much slower
+The created delegate will make use of reflection to evaluate the expression when it is invoked. This is much slower
than executing a compiled delegate of an expression!
-This framework is intended to be used where dynamic code creation is not possible. The main purpose is the useage with
+This framework is intended to be used where dynamic code creation is not possible. The main purpose is the usage with
Xamarin.iOS due to it's restriction on Reflection.Emit.
How?
@@ -197,4 +197,7 @@ All this features can be combined to more complex expressions.
Contributors
------------
-Bernhard Richter (seesharper)
\ No newline at end of file
+Bernhard Richter (seesharper)
+
+
+Thank you!
\ No newline at end of file
diff --git a/Source/ExpressionReflect.Tests/BinaryOperatorTests.cs b/Source/ExpressionReflect.Tests/BinaryOperatorTests.cs
index 0a62f65..c97db39 100644
--- a/Source/ExpressionReflect.Tests/BinaryOperatorTests.cs
+++ b/Source/ExpressionReflect.Tests/BinaryOperatorTests.cs
@@ -76,43 +76,43 @@ public void ShouldExecuteOperator_TypeIs()
reflectionResult.Should().Be(emitResult);
}
- [Test]
- public void ShouldExecuteOperator_Equals()
- {
- // Arrange
- Expression> expression = s => s == "SomeValue";
-
- // Act
- Func emit = expression.Compile();
- Func reflection = expression.Reflect();
-
- bool emitResult = emit.Invoke("SomeValue");
- bool reflectionResult = reflection.Invoke("SomeValue");
-
- // Assert
- emitResult.Should().BeTrue();
- reflectionResult.Should().BeTrue();
- reflectionResult.Should().Be(emitResult);
- }
-
- [Test]
- public void ShouldExecuteOperator_EqualsWithNullValue()
- {
- // Arrange
- Expression> expression = s => s == null;
-
- // Act
- Func emit = expression.Compile();
- Func reflection = expression.Reflect();
-
- bool emitResult = emit.Invoke(null);
- bool reflectionResult = reflection.Invoke(null);
-
- // Assert
- emitResult.Should().BeTrue();
- reflectionResult.Should().BeTrue();
- reflectionResult.Should().Be(emitResult);
- }
+ [Test]
+ public void ShouldExecuteOperator_Equals()
+ {
+ // Arrange
+ Expression> expression = s => s == "SomeValue";
+
+ // Act
+ Func emit = expression.Compile();
+ Func reflection = expression.Reflect();
+
+ bool emitResult = emit.Invoke("SomeValue");
+ bool reflectionResult = reflection.Invoke("SomeValue");
+
+ // Assert
+ emitResult.Should().BeTrue();
+ reflectionResult.Should().BeTrue();
+ reflectionResult.Should().Be(emitResult);
+ }
+
+ [Test]
+ public void ShouldExecuteOperator_EqualsWithNullValue()
+ {
+ // Arrange
+ Expression> expression = s => s == null;
+
+ // Act
+ Func emit = expression.Compile();
+ Func reflection = expression.Reflect();
+
+ bool emitResult = emit.Invoke(null);
+ bool reflectionResult = reflection.Invoke(null);
+
+ // Assert
+ emitResult.Should().BeTrue();
+ reflectionResult.Should().BeTrue();
+ reflectionResult.Should().Be(emitResult);
+ }
}
}
diff --git a/Source/ExpressionReflect.Tests/EvaluatorTests.cs b/Source/ExpressionReflect.Tests/EvaluatorTests.cs
index ddd2e19..afb2f3a 100644
--- a/Source/ExpressionReflect.Tests/EvaluatorTests.cs
+++ b/Source/ExpressionReflect.Tests/EvaluatorTests.cs
@@ -2,6 +2,9 @@
namespace ExpressionReflect.Tests
{
using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Linq;
using System.Linq.Expressions;
using ExpressionReflect.Tests.Model;
using FluentAssertions;
@@ -35,10 +38,10 @@ public void ShouldPreEvaluate_LocalVariable()
{
// Arrange
string str = "test";
- Expression> expresion = x => x.Firstname == str;
+ Expression> expression = x => x.Firstname == str;
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -50,10 +53,10 @@ public void ShouldPreEvaluate_LocalFuncWithoutParameter()
{
// Arrange
Func func = () => "test";
- Expression> expresion = x => x.Firstname == func();
+ Expression> expression = x => x.Firstname == func();
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -65,10 +68,10 @@ public void ShouldPreEvaluate_LocalFuncWithConstantParameter()
{
// Arrange
Func func = x => "test" + x;
- Expression> expresion = x => x.Firstname == func(5);
+ Expression> expression = x => x.Firstname == func(5);
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -81,10 +84,10 @@ public void ShouldPreEvaluate_LocalFuncWithLocalVariableParameter()
// Arrange
Func func = x => "test" + x;
int i = 5;
- Expression> expresion = x => x.Firstname == func(i);
+ Expression> expression = x => x.Firstname == func(i);
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -97,10 +100,10 @@ public void ShouldPreEvaluate_LocalFuncWithLocalFuncParameter()
// Arrange
Func func = x => "test" + x;
Func i = () => 5;
- Expression> expresion = x => x.Firstname == func(i());
+ Expression> expression = x => x.Firstname == func(i());
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -111,10 +114,10 @@ public void ShouldPreEvaluate_LocalFuncWithLocalFuncParameter()
public void ShouldPreEvaluate_InstanceMethodCallWithoutParameter()
{
// Arrange
- Expression> expresion = x => x.Firstname == this.GetString();
+ Expression> expression = x => x.Firstname == this.GetString();
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -125,10 +128,10 @@ public void ShouldPreEvaluate_InstanceMethodCallWithoutParameter()
public void ShouldPreEvaluate_StaticMethodCallWithoutParameter()
{
// Arrange
- Expression> expresion = x => x.Firstname == GetStringStatic();
+ Expression> expression = x => x.Firstname == GetStringStatic();
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -139,10 +142,10 @@ public void ShouldPreEvaluate_StaticMethodCallWithoutParameter()
public void ShouldPreEvaluate_InstanceMethodCallWithConstantParameter()
{
// Arrange
- Expression> expresion = x => x.Firstname == this.GetString(5);
+ Expression> expression = x => x.Firstname == this.GetString(5);
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -153,10 +156,10 @@ public void ShouldPreEvaluate_InstanceMethodCallWithConstantParameter()
public void ShouldPreEvaluate_StaticMethodCallWithConstantParameter()
{
// Arrange
- Expression> expresion = x => x.Firstname == GetStringStatic(5);
+ Expression> expression = x => x.Firstname == GetStringStatic(5);
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -168,10 +171,10 @@ public void ShouldPreEvaluate_InstanceMethodCallWithLocalVariableParameter()
{
// Arrange
int i = 5;
- Expression> expresion = x => x.Firstname == this.GetString(i);
+ Expression> expression = x => x.Firstname == this.GetString(i);
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -183,10 +186,10 @@ public void ShouldPreEvaluate_StaticMethodCallWithLocalVariableParameter()
{
// Arrange
int i = 5;
- Expression> expresion = x => x.Firstname == GetStringStatic(i);
+ Expression> expression = x => x.Firstname == GetStringStatic(i);
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -198,10 +201,10 @@ public void ShouldPreEvaluate_InstanceMethodCallWithLocalFuncParameter()
{
// Arrange
Func i = () => 5;
- Expression> expresion = x => x.Firstname == this.GetString(i());
+ Expression> expression = x => x.Firstname == this.GetString(i());
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
@@ -213,29 +216,46 @@ public void ShouldPreEvaluate_StaticMethodCallWithLocalFuncParameter()
{
// Arrange
Func i = () => 5;
- Expression> expresion = x => x.Firstname == GetStringStatic(i());
+ Expression> expression = x => x.Firstname == GetStringStatic(i());
// Act
- string expressionString = expresion.PartialEval().ToString();
+ string expressionString = expression.PartialEval().ToString();
Console.WriteLine(expressionString);
// Assert
expressionString.Should().Be(@"x => (x.Firstname == ""test5"")");
}
+ //[Test]
+ //public void ShouldPreEvaluate_LocalFuncWithLambdaParameterParameter()
+ //{
+ // // Arrange
+ // Func func = x => x;
+ // Expression> expression = x => x.Firstname == func(x.Lastname);
+
+ // // Act
+ // string expressionString = expression.PartialEval().ToString();
+ // Console.WriteLine(expressionString);
+
+ // // Assert
+ // expressionString.Should().Be(@"x => (x.Firstname == func(x.Lastname))");
+ //}
+
[Test]
- public void ShouldPreEvaluate_LocalFuncWithLambdaParameterParameter()
+ public void ShouldPreEvaluate_LocalCollectionContains()
{
// Arrange
- Func func = x => x;
- Expression> expresion = x => x.Firstname == func(x.Lastname);
+ var ids = new List { 4, 5, 7 };
+ Expression> expression = x => ids.Contains(x.Age);
// Act
- string expressionString = expresion.PartialEval().ToString();
+ Expression exp = expression.PartialEval();
+ exp = exp.ExpandCollection();
+ string expressionString = exp.ToString();
Console.WriteLine(expressionString);
// Assert
- expressionString.Should().Be(@"x => (x.Firstname == func(x.Lastname))");
+ expressionString.Should().Be(@"x => {4|5|7}.Contains(x.Age)");
}
}
}
diff --git a/Source/ExpressionReflect.Tests/ExpressionReflect.Tests.csproj b/Source/ExpressionReflect.Tests/ExpressionReflect.Tests.csproj
index cc68cb3..0fcab5d 100644
--- a/Source/ExpressionReflect.Tests/ExpressionReflect.Tests.csproj
+++ b/Source/ExpressionReflect.Tests/ExpressionReflect.Tests.csproj
@@ -9,10 +9,11 @@
Properties
ExpressionReflect.Tests
ExpressionReflect.Tests
- v4.5
+ v4.5.1
512
..\
true
+
true
@@ -32,12 +33,6 @@
4
-
- ..\packages\FluentAssertions.2.0.1\lib\net45\FluentAssertions.dll
-
-
- ..\packages\NUnit.2.6.2\lib\nunit.framework.dll
-
@@ -45,6 +40,15 @@
+
+ ..\packages\NUnit.2.6.3\lib\nunit.framework.dll
+
+
+ ..\packages\FluentAssertions.3.2.1\lib\net45\FluentAssertions.Core.dll
+
+
+ ..\packages\FluentAssertions.3.2.1\lib\net45\FluentAssertions.dll
+
@@ -67,7 +71,7 @@
- {320289ae-b78b-4c5a-b52e-08f81ae7f2ed}
+ {320289AE-B78B-4C5A-B52E-08F81AE7F2ED}
ExpressionReflect
diff --git a/Source/ExpressionReflect.Tests/FuncExecutionTests.cs b/Source/ExpressionReflect.Tests/FuncExecutionTests.cs
index eba06a4..7e215da 100644
--- a/Source/ExpressionReflect.Tests/FuncExecutionTests.cs
+++ b/Source/ExpressionReflect.Tests/FuncExecutionTests.cs
@@ -54,41 +54,41 @@ public void ShouldCreateSimpleFunc_PropertyGetter()
reflectionResult.Should().Be(emitResult);
}
- [Test]
- public void ShouldCreateSimpleFunc_StaticPropertyGetter()
- {
- //Arrange
- Expression> expression = () => Customer.StaticProperty;
-
- //Act
- Func emit = expression.Compile();
- Func reflection = expression.Reflect();
-
- string emitResult = emit.Invoke();
- string reflectionResult = reflection.Invoke();
-
- //Assert
- emitResult.Should().Be("StaticProperty");
- reflectionResult.Should().Be("StaticProperty");
- }
-
- [Test]
- public void ShouldCreateSimpleFunc_StaticField()
- {
- //Arrange
- Expression> expression = () => Customer.StaticField;
-
- //Act
- Func emit = expression.Compile();
- Func reflection = expression.Reflect();
-
- string emitResult = emit.Invoke();
- string reflectionResult = reflection.Invoke();
-
- //Assert
- emitResult.Should().Be("StaticField");
- reflectionResult.Should().Be("StaticField");
- }
+ [Test]
+ public void ShouldCreateSimpleFunc_StaticPropertyGetter()
+ {
+ //Arrange
+ Expression> expression = () => Customer.StaticProperty;
+
+ //Act
+ Func emit = expression.Compile();
+ Func reflection = expression.Reflect();
+
+ string emitResult = emit.Invoke();
+ string reflectionResult = reflection.Invoke();
+
+ //Assert
+ emitResult.Should().Be("StaticProperty");
+ reflectionResult.Should().Be("StaticProperty");
+ }
+
+ [Test]
+ public void ShouldCreateSimpleFunc_StaticField()
+ {
+ //Arrange
+ Expression> expression = () => Customer.StaticField;
+
+ //Act
+ Func emit = expression.Compile();
+ Func reflection = expression.Reflect();
+
+ string emitResult = emit.Invoke();
+ string reflectionResult = reflection.Invoke();
+
+ //Assert
+ emitResult.Should().Be("StaticField");
+ reflectionResult.Should().Be("StaticField");
+ }
[Test]
public void ShouldCreateSimpleFunc_PropertyGetter_MethodCall()
diff --git a/Source/ExpressionReflect.Tests/packages.config b/Source/ExpressionReflect.Tests/packages.config
index 9ac2dd5..446314d 100644
--- a/Source/ExpressionReflect.Tests/packages.config
+++ b/Source/ExpressionReflect.Tests/packages.config
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/Source/ExpressionReflect/ActionExtensions.cs b/Source/ExpressionReflect/ActionExtensions.cs
index e95d113..c94a646 100644
--- a/Source/ExpressionReflect/ActionExtensions.cs
+++ b/Source/ExpressionReflect/ActionExtensions.cs
@@ -34,5 +34,77 @@ public static Action Reflect(this Expression action = (a, b, c, d) => target.Execute(a, b, c, d);
return action;
}
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e) => target.Execute(a, b, c, d, e);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f) => target.Execute(a, b, c, d, e, f);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g) => target.Execute(a, b, c, d, e, f, g);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h) => target.Execute(a, b, c, d, e, f, g, h);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h, i) => target.Execute(a, b, c, d, e, f, g, h, i);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h, i, j) => target.Execute(a, b, c, d, e, f, g, h, i, j);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h, i, j, k) => target.Execute(a, b, c, d, e, f, g, h, i, j, k);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h, i, j, k, l) => target.Execute(a, b, c, d, e, f, g, h, i, j, k, l);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h, i, j, k, l, m) => target.Execute(a, b, c, d, e, f, g, h, i, j, k, l, m);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h, i, j, k, l, m, n) => target.Execute(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) => target.Execute(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
+ return action;
+ }
+
+ public static Action Reflect(this Expression> target)
+ {
+ Action action = (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) => target.Execute(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
+ return action;
+ }
}
}
\ No newline at end of file
diff --git a/Source/ExpressionReflect/Evaluator.cs b/Source/ExpressionReflect/Evaluator.cs
index 9cd7886..1811d5c 100644
--- a/Source/ExpressionReflect/Evaluator.cs
+++ b/Source/ExpressionReflect/Evaluator.cs
@@ -8,12 +8,12 @@
/// Enables the partial evaluation of queries.
///
///
- /// From http://msdn.microsoft.com/en-us/library/bb546158.aspx
+ /// From http://blogs.msdn.com/b/mattwar/archive/2007/08/01/linq-building-an-iqueryable-provider-part-iii.aspx
///
- public static class Evaluator
+ internal static class Evaluator
{
///
- /// Performs evaluation & replacement of independent sub-trees
+ /// Performs evaluation and replacement of independent sub-trees.
///
/// The root of the expression tree.
/// A new tree with sub-trees evaluated and replaced.
@@ -23,7 +23,7 @@ public static Expression PartialEval(this Expression expression)
}
///
- /// Performs evaluation & replacement of independent sub-trees
+ /// Performs evaluation and replacement of independent sub-trees.
///
/// The root of the expression tree.
/// A function that decides whether a given expression node can be part of the local function.
@@ -39,7 +39,7 @@ private static bool CanBeEvaluatedLocally(Expression expression)
}
///
- /// Evaluates & replaces sub-trees when first candidate is reached (top-down)
+ /// Evaluates and replaces sub-trees when first candidate is reached (top-down).
///
private class SubtreeEvaluator : ExpressionVisitor
{
@@ -57,11 +57,11 @@ internal Expression Eval(Expression exp)
public override Expression Visit(Expression exp)
{
- if (exp == null)
+ if(exp == null)
{
return null;
}
- if (this.candidates.ContainsKey(exp))
+ if(this.candidates.ContainsKey(exp))
{
return this.Evaluate(exp);
}
@@ -70,11 +70,12 @@ public override Expression Visit(Expression exp)
private Expression Evaluate(Expression e)
{
- if (e.NodeType == ExpressionType.Constant)
+ if(e.NodeType == ExpressionType.Constant)
{
return e;
}
+ // Note[mge]: Uses the expression evaluation instead of Expression.Compile().
LambdaExpression lambda = Expression.Lambda(e);
object value = lambda.Execute();
return Expression.Constant(value, e.Type);
@@ -105,14 +106,14 @@ internal IDictionary Nominate(Expression expression)
public override Expression Visit(Expression expression)
{
- if (expression != null)
+ if(expression != null)
{
bool saveCannotBeEvaluated = this.cannotBeEvaluated;
this.cannotBeEvaluated = false;
base.Visit(expression);
- if (!this.cannotBeEvaluated)
+ if(!this.cannotBeEvaluated)
{
- if (this.fnCanBeEvaluated(expression) && !this.candidates.ContainsKey(expression))
+ if(this.fnCanBeEvaluated(expression) && !this.candidates.ContainsKey(expression))
{
this.candidates.Add(expression, expression);
}
diff --git a/Source/ExpressionReflect/ExpressionExtensions.cs b/Source/ExpressionReflect/ExpressionExtensions.cs
index 9cddee5..0168fb2 100644
--- a/Source/ExpressionReflect/ExpressionExtensions.cs
+++ b/Source/ExpressionReflect/ExpressionExtensions.cs
@@ -10,5 +10,10 @@ public static object Execute(this Expression expression, params object[] values)
object result = visitor.Execute(values);
return result;
}
+
+ public static TResult Execute(this Expression expression, params object[] values)
+ {
+ return (TResult)expression.Execute(values);
+ }
}
}
\ No newline at end of file
diff --git a/Source/ExpressionReflect/ExpressionReflect.csproj b/Source/ExpressionReflect/ExpressionReflect.csproj
index 0f6a0f5..543ab1c 100644
--- a/Source/ExpressionReflect/ExpressionReflect.csproj
+++ b/Source/ExpressionReflect/ExpressionReflect.csproj
@@ -11,7 +11,7 @@
ExpressionReflect
ExpressionReflect
v4.0
- Profile154
+ Profile344
512
{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
@@ -38,9 +38,6 @@
4
bin\Release\ExpressionReflect.xml
-
- true
-
..\..\ExpressionReflect.snk
@@ -53,17 +50,13 @@
+
+
-
-
- ExpressionReflect.snk
-
-
-