Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 23 additions & 25 deletions Orm/Xtensive.Orm/Linq/ExpressionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created: 2009.04.21

using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
Expand All @@ -20,7 +21,10 @@ namespace Xtensive.Linq
/// </summary>
public static class ExpressionExtensions
{
private static readonly MethodInfo TupleGenericAccessor;
private static readonly ConcurrentDictionary<Type, MethodInfo> valueAccessors =
new ConcurrentDictionary<Type, MethodInfo>();

private static readonly Func<Type, MethodInfo> TupleValueAccessorFactory;

///<summary>
/// Makes <see cref="Tuples.Tuple.GetValueOrDefault{T}"/> method call.
Expand All @@ -29,15 +33,12 @@ public static class ExpressionExtensions
///<param name="accessorType">Type of accessor.</param>
///<param name="index">Tuple field index.</param>
///<returns><see cref="MethodCallExpression"/></returns>
public static MethodCallExpression MakeTupleAccess(this Expression target, Type accessorType, int index)
{
return Expression.Call(
public static MethodCallExpression MakeTupleAccess(this Expression target, Type accessorType, int index) =>
Expression.Call(
target,
TupleGenericAccessor.MakeGenericMethod(accessorType),
valueAccessors.GetOrAdd(accessorType, TupleValueAccessorFactory),
Expression.Constant(index)
);
}

);

/// <summary>
/// Makes <c>IsNull</c> condition expression.
Expand All @@ -46,41 +47,38 @@ public static MethodCallExpression MakeTupleAccess(this Expression target, Type
/// <param name="ifNull">Result expression if <paramref name="target"/> is <see langword="null" />.</param>
/// <param name="ifNotNull">Result expression if <paramref name="target"/> is not <see langword="null" />.</param>
/// <returns><see cref="ConditionalExpression"/></returns>
public static ConditionalExpression MakeIsNullCondition(this Expression target, Expression ifNull, Expression ifNotNull)
{
return Expression.Condition(
public static ConditionalExpression MakeIsNullCondition(
this Expression target, Expression ifNull, Expression ifNotNull) =>
Expression.Condition(
Expression.Equal(target, Expression.Constant(null, target.Type)),
ifNull, ifNotNull
);
}
ifNull,
ifNotNull
);

/// <summary>
/// Converts expression type to nullable type (for value types).
/// </summary>
/// <param name="expression">The expression.</param>
public static Expression LiftToNullable(this Expression expression)
{
return expression.Type.IsNullable()
? expression
: Expression.Convert(expression, expression.Type.ToNullable());
}
public static Expression LiftToNullable(this Expression expression) =>
expression.Type.IsNullable()
? expression
: Expression.Convert(expression, expression.Type.ToNullable());

/// <summary>
/// Converts specified <see cref="Expression"/> to <see cref="ExpressionTree"/>.
/// </summary>
/// <param name="expression">The expression to convert.</param>
/// <returns>Expression tree that wraps <paramref name="expression"/>.</returns>
public static ExpressionTree ToExpressionTree(this Expression expression)
{
return new ExpressionTree(expression);
}
public static ExpressionTree ToExpressionTree(this Expression expression) => new ExpressionTree(expression);


// Type initializer

static ExpressionExtensions()
{
TupleGenericAccessor = typeof (Tuple).GetMethods().Single(mi => mi.Name==WellKnown.Tuple.GetValueOrDefault && mi.IsGenericMethod);
var tupleGenericAccessor = typeof(Tuple).GetMethods()
.Single(mi => mi.Name == WellKnown.Tuple.GetValueOrDefault && mi.IsGenericMethod);
TupleValueAccessorFactory = type => tupleGenericAccessor.MakeGenericMethod(type);
}
}
}