예제 #1
0
        public static MetaObject Restrict(this MetaObject self, Type type)
        {
            ContractUtils.RequiresNotNull(self, "self");
            ContractUtils.RequiresNotNull(type, "type");

            IRestrictedMetaObject rmo = self as IRestrictedMetaObject;

            if (rmo != null)
            {
                return(rmo.Restrict(type));
            }

            if (type == self.Expression.Type)
            {
                if (type.IsSealedOrValueType())
                {
                    return(self);
                }

                if (self.Expression.NodeType == ExpressionType.New ||
                    self.Expression.NodeType == ExpressionType.NewArrayBounds ||
                    self.Expression.NodeType == ExpressionType.NewArrayInit)
                {
                    return(self);
                }
            }

            if (type == typeof(Null))
            {
                return(new MetaObject(
                           Expression.Constant(null),
                           self.Restrictions.Merge(Restrictions.GetInstanceRestriction(self.Expression, null)),
                           self.Value
                           ));
            }

            if (self.HasValue)
            {
                return(new MetaObject(
                           AstUtils.Convert(
                               self.Expression,
                               CompilerHelpers.GetVisibleType(type)
                               ),
                           self.Restrictions.Merge(Restrictions.GetTypeRestriction(self.Expression, type)),
                           self.Value
                           ));
            }

            return(new MetaObject(
                       AstUtils.Convert(
                           self.Expression,
                           CompilerHelpers.GetVisibleType(type)
                           ),
                       self.Restrictions.Merge(Restrictions.GetTypeRestriction(self.Expression, type))
                       ));
        }
        public static DynamicMetaObject Restrict(this DynamicMetaObject self, Type type)
        {
            ContractUtils.RequiresNotNull(self, "self");
            ContractUtils.RequiresNotNull(type, "type");

            IRestrictedMetaObject rmo = self as IRestrictedMetaObject;

            if (rmo != null)
            {
                return(rmo.Restrict(type));
            }

            if (type == self.Expression.Type)
            {
                if (type.IsSealed ||
                    self.Expression.NodeType == ExpressionType.New ||
                    self.Expression.NodeType == ExpressionType.NewArrayBounds ||
                    self.Expression.NodeType == ExpressionType.NewArrayInit)
                {
                    return(self.Clone(self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, type))));
                }
            }

            if (type == typeof(DynamicNull))
            {
                return(self.Clone(
                           AstUtils.Constant(null),
                           self.Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(self.Expression, null))
                           ));
            }

            Expression converted;

            // if we're converting to a value type just unbox to preserve
            // object identity.  If we're converting from Enum then we're
            // going to a specific enum value and an unbox is not allowed.
            if (type.IsValueType && self.Expression.Type != typeof(Enum))
            {
                converted = Expression.Unbox(
                    self.Expression,
                    CompilerHelpers.GetVisibleType(type)
                    );
            }
            else
            {
                converted = AstUtils.Convert(
                    self.Expression,
                    CompilerHelpers.GetVisibleType(type)
                    );
            }

            return(self.Clone(converted, self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, type))));
        }