diff --git a/src/IharBury.Expressions/BooleanExpressions.cs b/src/IharBury.Expressions/BooleanExpressions.cs index 2955e73..14eb4f2 100644 --- a/src/IharBury.Expressions/BooleanExpressions.cs +++ b/src/IharBury.Expressions/BooleanExpressions.cs @@ -607,7 +607,7 @@ private static LambdaExpression Combine( LambdaExpression firstExpression = null; Expression resultBody = null; - IReadOnlyList resultParameters = null; + IList resultParameters = null; foreach (var expression in expressions) { if (expression == null) diff --git a/src/IharBury.Expressions/CompatibilityExtensions.cs b/src/IharBury.Expressions/CompatibilityExtensions.cs new file mode 100644 index 0000000..6b61190 --- /dev/null +++ b/src/IharBury.Expressions/CompatibilityExtensions.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace IharBury.Expressions +{ + internal static class CompatibilityExtensions + { + internal static Type GetBaseType(this Type type) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + +#if NET40 + return type.BaseType; +#else + return type.GetTypeInfo().BaseType; +#endif + } + + internal static IEnumerable GetDeclaredProperties(this Type type) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + +#if NET40 + return (IEnumerable)type.GetProperties(BindingFlags.DeclaredOnly | + BindingFlags.Instance | + BindingFlags.Static | + BindingFlags.Public | + BindingFlags.NonPublic); +#else + return type.GetTypeInfo().DeclaredProperties; +#endif + } + + internal static bool GetIsConstructedGenericType(this Type type) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + +#if NET40 + return type.IsGenericType && !type.IsGenericTypeDefinition; +#else + return type.IsConstructedGenericType; +#endif + } + } +} diff --git a/src/IharBury.Expressions/ExpressionExpander.cs b/src/IharBury.Expressions/ExpressionExpander.cs index b3bbe48..87d7a63 100644 --- a/src/IharBury.Expressions/ExpressionExpander.cs +++ b/src/IharBury.Expressions/ExpressionExpander.cs @@ -8,14 +8,18 @@ namespace IharBury.Expressions { internal sealed class ExpressionExpander : ExpressionVisitor { - private static readonly MethodInfo MethodInfoCreateDelegateMethod = - ReflectionExpressions.GetMethodInfo(methodInfo => - methodInfo.CreateDelegate(default(Type), default(object))); - + private static readonly MethodInfo MethodInfoCreateDelegateMethod; private static readonly MethodInfo DelegateCreateDelegateMethod; static ExpressionExpander() { + MethodInfoCreateDelegateMethod = typeof(MethodInfo).GetMethod( + "CreateDelegate", + new[] + { + typeof(Type), + typeof(object) + }); DelegateCreateDelegateMethod = typeof(Delegate).GetMethod( "CreateDelegate", new[] @@ -65,7 +69,7 @@ private static bool IsCompileMethod(MethodInfo method) throw new ArgumentNullException(nameof(method)); return (method.DeclaringType != null) && - method.DeclaringType.IsConstructedGenericType && + method.DeclaringType.GetIsConstructedGenericType() && (method.DeclaringType.GetGenericTypeDefinition() == typeof(Expression<>)) && (method.Name == nameof(Expression>.Compile)); } @@ -104,7 +108,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node) } if ((baseResult.Method.DeclaringType != null) && - (baseResult.Method.DeclaringType.GetTypeInfo().BaseType == typeof(MulticastDelegate)) && + (baseResult.Method.DeclaringType.GetBaseType() == typeof(MulticastDelegate)) && (baseResult.Method.Name == nameof(Action.Invoke)) && (baseResult.Object != null) && (baseResult.Object.NodeType == ExpressionType.Call)) @@ -173,7 +177,7 @@ protected override Expression VisitUnary(UnaryExpression node) private bool TrySubstituteExpression( Expression expressionExpression, - IReadOnlyList arguments, + IList arguments, out Expression result) { if (expressionExpression == null) diff --git a/src/IharBury.Expressions/Extensions.cs b/src/IharBury.Expressions/Extensions.cs index 08be479..bc6e6d9 100644 --- a/src/IharBury.Expressions/Extensions.cs +++ b/src/IharBury.Expressions/Extensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Reflection; namespace IharBury.Expressions { diff --git a/src/IharBury.Expressions/ReflectionExpressions.cs b/src/IharBury.Expressions/ReflectionExpressions.cs index d6456c0..49d3ff0 100644 --- a/src/IharBury.Expressions/ReflectionExpressions.cs +++ b/src/IharBury.Expressions/ReflectionExpressions.cs @@ -325,8 +325,8 @@ public static PropertyInfo TryGetPropertyInfo(LambdaExpression propertyExpressio return methodCallExpression .Method .DeclaringType - .GetTypeInfo() - .DeclaredProperties.SingleOrDefault(property => property.GetMethod == methodCallExpression.Method); + .GetDeclaredProperties() + .SingleOrDefault(property => property.GetGetMethod() == methodCallExpression.Method); return null; default: diff --git a/src/IharBury.Expressions/project.json b/src/IharBury.Expressions/project.json index 6722104..a274a54 100644 --- a/src/IharBury.Expressions/project.json +++ b/src/IharBury.Expressions/project.json @@ -17,6 +17,7 @@ "System.Linq.Expressions": "4.0.10-*" } }, - "net45": { } + "net45": { }, + "net40": { } } } diff --git a/test/IharBury.Expressions.Tests/CompatibilityExtensions.cs b/test/IharBury.Expressions.Tests/CompatibilityExtensions.cs new file mode 100644 index 0000000..7f77c41 --- /dev/null +++ b/test/IharBury.Expressions.Tests/CompatibilityExtensions.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace IharBury.Expressions.Tests +{ + internal static class CompatibilityExtensions + { + internal static Type GetBaseType(this Type type) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + +#if NET40 + return type.BaseType; +#else + return type.GetTypeInfo().BaseType; +#endif + } + + internal static IEnumerable GetDeclaredProperties(this Type type) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + +#if NET40 + return (IEnumerable)type.GetProperties(BindingFlags.DeclaredOnly | + BindingFlags.Instance | + BindingFlags.Static | + BindingFlags.Public | + BindingFlags.NonPublic); +#else + return type.GetTypeInfo().DeclaredProperties; +#endif + } + + internal static bool GetIsConstructedGenericType(this Type type) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + +#if NET40 + return type.IsGenericType && !type.IsGenericTypeDefinition; +#else + return type.IsConstructedGenericType; +#endif + } + } +} diff --git a/test/IharBury.Expressions.Tests/ExpandExpressionTests.cs b/test/IharBury.Expressions.Tests/ExpandExpressionTests.cs index 39d0b18..3dbbf66 100644 --- a/test/IharBury.Expressions.Tests/ExpandExpressionTests.cs +++ b/test/IharBury.Expressions.Tests/ExpandExpressionTests.cs @@ -475,7 +475,7 @@ protected override Expression VisitInvocation(InvocationExpression node) var methodCallExpression = (MethodCallExpression)node.Expression; Assert.False( (methodCallExpression.Method.DeclaringType != null) && - methodCallExpression.Method.DeclaringType.IsConstructedGenericType && + methodCallExpression.Method.DeclaringType.GetIsConstructedGenericType() && (methodCallExpression.Method.DeclaringType.GetGenericTypeDefinition() == typeof(Expression<>)) && (methodCallExpression.Method.Name == CompileMethodName), $"The expression body has evaluation: \"{node}\"."); @@ -506,7 +506,7 @@ private static void ValidateMethod(Expression node, MethodInfo method) $"The expression body has evaluation: \"{node}\"."); Assert.False( (method.DeclaringType != null) && - (method.DeclaringType.GetTypeInfo().BaseType == typeof(MulticastDelegate)) && + (method.DeclaringType.GetBaseType() == typeof(MulticastDelegate)) && (method.Name == ReflectionExpressions.GetMethodName(action => action.Invoke())), $"The expression body has invokation: \"{node}\"."); } diff --git a/test/IharBury.Expressions.Tests/project.json b/test/IharBury.Expressions.Tests/project.json index c265e03..90db551 100644 --- a/test/IharBury.Expressions.Tests/project.json +++ b/test/IharBury.Expressions.Tests/project.json @@ -28,6 +28,12 @@ "xunit": "1.9.2", "xunit.runner.console": "2.0.0" } + }, + "net40": { + "dependencies": { + "xunit": "1.9.2", + "xunit.runner.console": "2.0.0" + } } } }