Ejemplo n.º 1
0
        public MappingTarget(MemberAccessPath memberSetter, MemberAccessPath memberGetter = null)
            : base(memberSetter)
        {
            this.ValueSetter = memberSetter.Count > 1 ?
                               memberSetter.GetSetterExpWithNullInstancesInstantiation() :
                               memberSetter.GetSetterExp();

            try
            {
                //build the getter from the getter member path if provided;
                //try to figure out the getter from the setter member path otherwise
                //(this will work if the member being accessed is a field or property
                //but won't necessarily work for methods)
                this.ValueGetter = memberGetter == null
                    ? memberSetter.GetGetterExp()
                    : memberGetter.GetGetterExp();
            }
            catch (Exception)
            {
                //Must be provided from where to read the member.
                //We don't always have the real need to 'read' the member being set (we need to write it).
                //This could still be not a problem.
            }
        }
Ejemplo n.º 2
0
        internal static LambdaExpression GetGetterExpWithNullChecks(this MemberAccessPath memberAccessPath)
        {
            if (memberAccessPath.Count == 0)
            {
                return(memberAccessPath.GetGetterExp());
            }

            if (memberAccessPath.Count == 1)
            {
                return(memberAccessPath.First().GetGetterExp());
            }

            var instanceType = memberAccessPath.EntryInstance;
            var entryMember  = memberAccessPath.First();

            var returnType = memberAccessPath.Last().GetMemberType();

            var entryInstance = Expression.Parameter(instanceType, "instance");
            var labelTarget   = Expression.Label(returnType, "label");

            Expression accessPath     = entryInstance;
            var        memberAccesses = new List <Expression>();

            foreach (var memberAccess in memberAccessPath)
            {
                if (memberAccess is MethodInfo mi)
                {
                    accessPath = Expression.Call(accessPath, mi);
                }
                else
                {
                    if (memberAccess.DeclaringType != accessPath.Type)
                    {
                        accessPath = Expression.Convert(accessPath, memberAccess.DeclaringType);
                    }

                    accessPath = Expression.MakeMemberAccess(accessPath, memberAccess);
                }

                memberAccesses.Add(accessPath);
            }

            var nullConstant = Expression.Constant(null);
            var returnNull   = Expression.Return(labelTarget, Expression.Default(returnType));

            var nullChecks = memberAccesses.Take(memberAccesses.Count - 1).Select(memberAccess =>
            {
                var equalsNull = Expression.Equal(memberAccess, nullConstant);
                return((Expression)Expression.IfThen(equalsNull, returnNull));
            }).ToList();

            var exp = Expression.Block
                      (
                nullChecks.Any() ? Expression.Block(nullChecks.ToArray())
                    : (Expression)Expression.Empty(),

                Expression.Label(labelTarget, memberAccesses.Last())
                      );

            var delegateType = typeof(Func <,>).MakeGenericType(instanceType, returnType);

            return(LambdaExpression.Lambda(delegateType, exp, entryInstance));
        }