protected static IValueInterface <T> Get <T>(long?id) { if (id == null) { return(null); } var guid = CreateGuid <T>(id.Value); if (cache.TryGetValue(guid, out var value)) { return((IValueInterface <T>)value); } return(null); }
public bool Equals(Expression x, Expression y) { if ((object)x == (object)y) return true; if (x == null || y == null) return false; var type = x.NodeType; if (y.NodeType != type) return false; if (x.Type != y.Type) return false; if (HashCache != null && HashCache.TryGetValue(x, out var hashx) && HashCache.TryGetValue(x, out var hashy) && hashy.Item1 != hashx.Item1) return false; switch (type) { case ExpressionType.Add: case ExpressionType.AddChecked: case ExpressionType.And: case ExpressionType.Divide: case ExpressionType.Equal: case ExpressionType.ExclusiveOr: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.AndAlso: case ExpressionType.Power: case ExpressionType.RightShift: case ExpressionType.Subtract: case ExpressionType.SubtractChecked: case ExpressionType.ArrayIndex: case ExpressionType.Modulo: case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: case ExpressionType.LeftShift: case ExpressionType.OnesComplement: case ExpressionType.AddAssign: case ExpressionType.AndAssign: case ExpressionType.DivideAssign: case ExpressionType.ExclusiveOrAssign: case ExpressionType.LeftShiftAssign: case ExpressionType.ModuloAssign: case ExpressionType.MultiplyAssign: case ExpressionType.OrAssign: case ExpressionType.PowerAssign: case ExpressionType.RightShiftAssign: case ExpressionType.SubtractAssign: case ExpressionType.AddAssignChecked: case ExpressionType.MultiplyAssignChecked: case ExpressionType.SubtractAssignChecked: case ExpressionType.PreIncrementAssign: case ExpressionType.PreDecrementAssign: case ExpressionType.PostIncrementAssign: case ExpressionType.PostDecrementAssign: case ExpressionType.IsTrue: case ExpressionType.IsFalse: case ExpressionType.NotEqual: case ExpressionType.Or: case ExpressionType.OrElse: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: case ExpressionType.Coalesce: var binX = (BinaryExpression)x; var binY = (BinaryExpression)y; return Equals(binX.Method, binY.Method) && Equals(binX.Left, binY.Left) && Equals(binX.Right, binY.Right); case ExpressionType.Call: var callX = (MethodCallExpression)x; var callY = (MethodCallExpression)y; return Equals(callX.Method, callY.Method) && Equals(callX.Object, callY.Object) && callX.Arguments.Zip(callY.Arguments, Equals).All(f => f); case ExpressionType.ConvertChecked: case ExpressionType.Negate: case ExpressionType.UnaryPlus: case ExpressionType.Quote: case ExpressionType.Not: case ExpressionType.TypeAs: case ExpressionType.NegateChecked: case ExpressionType.Unbox: case ExpressionType.Convert: case ExpressionType.ArrayLength: var unX = (UnaryExpression)x; var unY = (UnaryExpression)y; return Equals(unX.Method, unY.Method) && Equals(unX.Operand, unY.Operand); case ExpressionType.Conditional: var condX = (ConditionalExpression)x; var condY = (ConditionalExpression)y; return Equals(condX.IfFalse, condY.IfFalse) && Equals(condX.IfTrue, condY.IfTrue) && Equals(condX.Test, condY.Test); case ExpressionType.Constant: var constX = (ConstantExpression)x; var constY = (ConstantExpression)y; return constX.Value == constY.Value || constX.Value.Equals(constY.Value); case ExpressionType.Invoke: var invX = (InvocationExpression)x; var invY = (InvocationExpression)y; return Equals(invX.Expression, invY.Expression) && invX.Arguments.Zip(invY.Arguments, Equals).All(f => f); case ExpressionType.Lambda: var lamX = (LambdaExpression)x; var lamY = (LambdaExpression)y; return lamX.Name == lamY.Name && lamX.Parameters.Count == lamY.Parameters.Count && lamX.Parameters.Zip(lamY.Parameters, Equals).All(f => f) && Equals(lamX.Body, lamY.Body); case ExpressionType.ListInit: var linitX = (ListInitExpression)x; var linitY = (ListInitExpression)y; return Equals(linitX.NewExpression, linitY.NewExpression) && linitX.Initializers.Zip(linitY.Initializers, Equals).All(f => f); case ExpressionType.MemberAccess: var memX = (MemberExpression)x; var memY = (MemberExpression)y; return Equals(memX.Member, memY.Member) && Equals(memX.Expression, memY.Expression); case ExpressionType.MemberInit: var minitX = (MemberInitExpression)x; var minitY = (MemberInitExpression)y; throw new NotImplementedException(); //return Equals(minitX, minitY) && minitX.Bindings.Zip(minitY.Bindings, (a, b) => a.BindingType == b.BindingType && a.Member == b.Member).All(f => f); case ExpressionType.New: var newX = (NewExpression)x; var newY = (NewExpression)y; return Equals(newX.Constructor, newY.Constructor) && newX.Arguments.Zip(newY.Arguments, Equals).All(f => f); case ExpressionType.NewArrayInit: case ExpressionType.NewArrayBounds: var newArrX = (NewArrayExpression)x; var newArrY = (NewArrayExpression)y; return newArrX.Expressions.Zip(newArrY.Expressions, Equals).All(f => f); case ExpressionType.Parameter: var paramX = (ParameterExpression)x; var paramY = (ParameterExpression)y; return paramX.Name == paramY.Name && paramX.IsByRef == paramY.IsByRef && paramX.Name != null && !paramX.Name.StartsWith("__"); case ExpressionType.TypeEqual: case ExpressionType.TypeIs: var typeBinX = (TypeBinaryExpression)x; var typeBinY = (TypeBinaryExpression)y; return typeBinX.TypeOperand == typeBinY.TypeOperand && Equals(typeBinX.Expression, typeBinY.Expression); case ExpressionType.Default: return true; case ExpressionType.Block: var blockX = (BlockExpression)x; var blockY = (BlockExpression)y; return blockX.Variables.SequenceEqual(blockY.Variables, this) && blockY.Expressions.SequenceEqual(blockY.Expressions, this); case ExpressionType.Index: var indexX = (IndexExpression)x; var indexY = (IndexExpression)y; return Equals(indexX.Indexer, indexY.Indexer) && indexX.Arguments.SequenceEqual(indexY.Arguments, this) && Equals(indexX.Object, indexY.Object); case ExpressionType.Extension: //Debug.Assert(x is MyParameterExpression); return x.Equals(y); default: throw new NotImplementedException($"Comparing expression of type { type} is not supported."); } }