ExpressionWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / ALinq / ExpressionWriter.cs / 1 / ExpressionWriter.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Serializes sub-expressions as query options in the URI.
//  
// 
// @owner  [....]
//--------------------------------------------------------------------- 

namespace System.Data.Services.Client
{
    #region Namespaces. 

    using System; 
    using System.Data.Services.Parsing; 
    using System.Diagnostics;
    using System.Linq.Expressions; 
    using System.Reflection;
    using System.Text;

    #endregion Namespaces. 

    ///  
    /// Special visitor to serialize supported expression as query parameters 
    /// in the generated URI.
    ///  
    internal class ExpressionWriter : DataServiceExpressionVisitor
    {
        /// Internal buffer.
        private readonly StringBuilder builder; 

        /// Data context used to generate type names for types. 
        private readonly DataServiceContext context; 

        /// set if can't translate expression 
        private bool cantTranslateExpression;

        /// 
        /// Creates an ExpressionWriter 
        /// 
        /// Data context used to generate type names for types. 
        private ExpressionWriter(DataServiceContext context) 
        {
            Debug.Assert(context != null, "context != null"); 
            this.context = context;
            this.builder = new StringBuilder();
        }
 
        /// 
        /// Serializes an expression to a string 
        ///  
        /// Data context used to generate type names for types.
        /// Expression to serialize 
        /// serialized expression
        internal static string ExpressionToString(DataServiceContext context, Expression e)
        {
            ExpressionWriter ew = new ExpressionWriter(context); 
            string serialized = ew.Translate(e);
            if (ew.cantTranslateExpression) 
            { 
                throw new NotSupportedException(Strings.ALinq_CantTranslateExpression(e.ToString()));
            } 

            return serialized;
        }
 
        /// 
        /// ConditionalExpression visit method 
        ///  
        /// The ConditionalExpression expression to visit
        /// The visited ConditionalExpression expression  
        internal override Expression VisitConditional(ConditionalExpression c)
        {
            this.cantTranslateExpression = true;
            return c; 
        }
 
        ///  
        /// LambdaExpression visit method
        ///  
        /// The LambdaExpression to visit
        /// The visited LambdaExpression
        internal override Expression VisitLambda(LambdaExpression lambda)
        { 
            this.cantTranslateExpression = true;
            return lambda; 
        } 

        ///  
        /// NewExpression visit method
        /// 
        /// The NewExpression to visit
        /// The visited NewExpression 
        internal override NewExpression VisitNew(NewExpression nex)
        { 
            this.cantTranslateExpression = true; 
            return nex;
        } 

        /// 
        /// MemberInitExpression visit method
        ///  
        /// The MemberInitExpression to visit
        /// The visited MemberInitExpression 
        internal override Expression VisitMemberInit(MemberInitExpression init) 
        {
            this.cantTranslateExpression = true; 
            return init;
        }

        ///  
        /// ListInitExpression visit method
        ///  
        /// The ListInitExpression to visit 
        /// The visited ListInitExpression
        internal override Expression VisitListInit(ListInitExpression init) 
        {
            this.cantTranslateExpression = true;
            return init;
        } 

        ///  
        /// NewArrayExpression visit method 
        /// 
        /// The NewArrayExpression to visit 
        /// The visited NewArrayExpression
        internal override Expression VisitNewArray(NewArrayExpression na)
        {
            this.cantTranslateExpression = true; 
            return na;
        } 
 
        /// 
        /// InvocationExpression visit method 
        /// 
        /// The InvocationExpression to visit
        /// The visited InvocationExpression
        internal override Expression VisitInvocation(InvocationExpression iv) 
        {
            this.cantTranslateExpression = true; 
            return iv; 
        }
 
        /// 
        /// Input resource set references are intentionally omitted from the URL string.
        /// 
        /// The input reference 
        /// The same input reference expression
        internal override Expression VisitInputReferenceExpression(InputReferenceExpression ire) 
        { 
            // This method intentionally does not write anything to the URI.
            // This is how 'Where(.Id == 5)' becomes '$filter=Id eq 5'. 
            return ire;
        }

        ///  
        /// MethodCallExpression visit method
        ///  
        /// The MethodCallExpression expression to visit 
        /// The visited MethodCallExpression expression 
        internal override Expression VisitMethodCall(MethodCallExpression m) 
        {
            string methodName;
            if (TypeSystem.TryGetQueryOptionMethod(m.Method, out methodName))
            { 
                this.builder.Append(methodName);
                this.builder.Append(UriHelper.LEFTPAREN); 
 
                // There is a single function, 'substringof', which reorders its argument with
                // respect to the CLR method. Thus handling it as a special case rather than 
                // using a more general argument reordering mechanism.
                if (methodName == "substringof")
                {
                    Debug.Assert(m.Method.Name == "Contains", "m.Method.Name == 'Contains'"); 
                    Debug.Assert(m.Object != null, "m.Object != null");
                    Debug.Assert(m.Arguments.Count == 1, "m.Arguments.Count == 1"); 
                    this.Visit(m.Arguments[0]); 
                    this.builder.Append(UriHelper.COMMA);
                    this.Visit(m.Object); 
                }
                else
                {
                    if (m.Object != null) 
                    {
                        this.Visit(m.Object); 
                    } 

                    if (m.Arguments.Count > 0) 
                    {
                        if (m.Object != null)
                        {
                            this.builder.Append(UriHelper.COMMA); 
                        }
 
                        for (int ii = 0; ii < m.Arguments.Count; ii++) 
                        {
                            this.Visit(m.Arguments[ii]); 
                            if (ii < m.Arguments.Count - 1)
                            {
                                this.builder.Append(UriHelper.COMMA);
                            } 
                        }
                    } 
                } 

                this.builder.Append(UriHelper.RIGHTPAREN); 
            }
            else
            {
                this.cantTranslateExpression = true; 
            }
 
            return m; 
        }
 
        /// 
        /// Serializes an MemberExpression to a string
        /// 
        /// Expression to serialize 
        /// MemberExpression
        internal override Expression VisitMemberAccess(MemberExpression m) 
        { 
            if (m.Member is FieldInfo)
            { 
                throw new NotSupportedException(Strings.ALinq_CantReferToPublicField(m.Member.Name));
            }

            Expression e = this.Visit(m.Expression); 
            if (!IsInputReference(e))
            { 
                this.builder.Append(UriHelper.FORWARDSLASH); 
            }
 
            this.builder.Append(m.Member.Name);

            return m;
        } 

        ///  
        /// ConstantExpression visit method 
        /// 
        /// The ConstantExpression expression to visit 
        /// The visited ConstantExpression expression 
        internal override Expression VisitConstant(ConstantExpression c)
        {
            string result = null; 
            if (c.Value == null)
            { 
                this.builder.Append(UriHelper.NULL); 
                return c;
            } 
            else if (!ClientConvert.TryKeyPrimitiveToString(c.Value, out result))
            {
                throw new InvalidOperationException(Strings.ALinq_CouldNotConvert(c.Value));
            } 

            Debug.Assert(result != null, "result != null"); 
            this.builder.Append(result); 
            return c;
        } 

        /// 
        /// Serializes an UnaryExpression to a string
        ///  
        /// Expression to serialize
        /// UnaryExpression 
        internal override Expression VisitUnary(UnaryExpression u) 
        {
            switch (u.NodeType) 
            {
                case ExpressionType.Not:
                    this.builder.Append(UriHelper.NOT);
                    this.builder.Append(UriHelper.SPACE); 
                    this.VisitOperand(u.Operand);
                    break; 
                case ExpressionType.Negate: 
                case ExpressionType.NegateChecked:
                    this.builder.Append(UriHelper.SPACE); 
                    this.builder.Append(UriHelper.NEGATE);
                    this.VisitOperand(u.Operand);
                    break;
                case ExpressionType.Convert: 
                case ExpressionType.ConvertChecked:
                    this.builder.Append(UriHelper.CAST); 
                    this.builder.Append(UriHelper.LEFTPAREN); 
                    if (!IsInputReference(u.Operand))
                    { 
                        this.Visit(u.Operand);
                        this.builder.Append(UriHelper.COMMA);
                    }
 
                    this.builder.Append(UriHelper.QUOTE);
                    this.builder.Append(this.TypeNameForUri(u.Type)); 
                    this.builder.Append(UriHelper.QUOTE); 
                    this.builder.Append(UriHelper.RIGHTPAREN);
                    break; 
                case ExpressionType.UnaryPlus:
                    // no-op always ignore.
                    break;
                default: 
                    this.cantTranslateExpression = true;
                    break; 
            } 

            return u; 
        }

        /// 
        /// Serializes an BinaryExpression to a string 
        /// 
        /// BinaryExpression to serialize 
        /// serialized expression 
        internal override Expression VisitBinary(BinaryExpression b)
        { 
            this.VisitOperand(b.Left);
            this.builder.Append(UriHelper.SPACE);
            switch (b.NodeType)
            { 
                case ExpressionType.AndAlso:
                case ExpressionType.And: 
                    this.builder.Append(UriHelper.AND); 
                    break;
                case ExpressionType.OrElse: 
                case ExpressionType.Or:
                    this.builder.Append(UriHelper.OR);
                    break;
                case ExpressionType.Equal: 
                    this.builder.Append(UriHelper.EQ);
                    break; 
                case ExpressionType.NotEqual: 
                    this.builder.Append(UriHelper.NE);
                    break; 
                case ExpressionType.LessThan:
                    this.builder.Append(UriHelper.LT);
                    break;
                case ExpressionType.LessThanOrEqual: 
                    this.builder.Append(UriHelper.LE);
                    break; 
                case ExpressionType.GreaterThan: 
                    this.builder.Append(UriHelper.GT);
                    break; 
                case ExpressionType.GreaterThanOrEqual:
                    this.builder.Append(UriHelper.GE);
                    break;
                case ExpressionType.Add: 
                case ExpressionType.AddChecked:
                    this.builder.Append(UriHelper.ADD); 
                    break; 
                case ExpressionType.Subtract:
                case ExpressionType.SubtractChecked: 
                    this.builder.Append(UriHelper.SUB);
                    break;
                case ExpressionType.Multiply:
                case ExpressionType.MultiplyChecked: 
                    this.builder.Append(UriHelper.MUL);
                    break; 
                case ExpressionType.Divide: 
                    this.builder.Append(UriHelper.DIV);
                    break; 
                case ExpressionType.Modulo:
                    this.builder.Append(UriHelper.MOD);
                    break;
                case ExpressionType.ArrayIndex: 
                case ExpressionType.Power:
                case ExpressionType.Coalesce: 
                case ExpressionType.ExclusiveOr: 
                case ExpressionType.LeftShift:
                case ExpressionType.RightShift: 
                default:
                    this.cantTranslateExpression = true;
                    break;
            } 

            this.builder.Append(UriHelper.SPACE); 
            this.VisitOperand(b.Right); 
            return b;
        } 

        /// 
        /// Serializes an TypeBinaryExpression to a string
        ///  
        /// TypeBinaryExpression to serialize
        /// serialized expression 
        internal override Expression VisitTypeIs(TypeBinaryExpression b) 
        {
            this.builder.Append(UriHelper.ISOF); 
            this.builder.Append(UriHelper.LEFTPAREN);

            if (!IsInputReference(b.Expression))
            { 
                this.Visit(b.Expression);
                this.builder.Append(UriHelper.COMMA); 
                this.builder.Append(UriHelper.SPACE); 
            }
 
            this.builder.Append(UriHelper.QUOTE);
            this.builder.Append(this.TypeNameForUri(b.TypeOperand));
            this.builder.Append(UriHelper.QUOTE);
            this.builder.Append(UriHelper.RIGHTPAREN); 

            return b; 
        } 

        ///  
        /// ParameterExpression visit method.
        /// 
        /// The ParameterExpression expression to visit
        /// The visited ParameterExpression expression  
        internal override Expression VisitParameter(ParameterExpression p)
        { 
            return p; 
        }
 
        /// 
        /// References to the current input - the resource set - do not appear in the URL.
        /// 
        /// The expression to test 
        /// true if the expression represents a reference to the current (resource set) input; otherwise false.
        private static bool IsInputReference(Expression exp) 
        { 
            return (exp is InputReferenceExpression || exp is ParameterExpression);
        } 

        /// Gets the type name to be used in the URI for the given .
        /// Type to get name for.
        /// The name for the , suitable for including in a URI. 
        private string TypeNameForUri(Type type)
        { 
            Debug.Assert(type != null, "type != null"); 
            type = Nullable.GetUnderlyingType(type) ?? type;
 
            if (ClientConvert.IsKnownType(type))
            {
                if (ClientConvert.IsSupportedPrimitiveTypeForUri(type))
                { 
                    return ClientConvert.ToTypeName(type);
                } 
 
                // unsupported primitive type
                throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(type.Name)); 
            }
            else
            {
                return this.context.ResolveNameFromType(type) ?? type.FullName; 
            }
        } 
 
        /// 
        /// Visits operands for Binary and Unary expressions. 
        /// Will only output parens if operand is complex expression,
        /// this is so don't have unecessary parens in URI.
        /// 
        /// The operand expression to visit 
        private void VisitOperand(Expression e)
        { 
            if (e is BinaryExpression || e is UnaryExpression) 
            {
                this.builder.Append(UriHelper.LEFTPAREN); 
                this.Visit(e);
                this.builder.Append(UriHelper.RIGHTPAREN);
            }
            else 
            {
                this.Visit(e); 
            } 
        }
 
        /// 
        /// Serializes an expression to a string
        /// 
        /// Expression to serialize 
        /// serialized expression
        private string Translate(Expression e) 
        { 
            this.Visit(e);
            return this.builder.ToString(); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Serializes sub-expressions as query options in the URI.
//  
// 
// @owner  [....]
//--------------------------------------------------------------------- 

namespace System.Data.Services.Client
{
    #region Namespaces. 

    using System; 
    using System.Data.Services.Parsing; 
    using System.Diagnostics;
    using System.Linq.Expressions; 
    using System.Reflection;
    using System.Text;

    #endregion Namespaces. 

    ///  
    /// Special visitor to serialize supported expression as query parameters 
    /// in the generated URI.
    ///  
    internal class ExpressionWriter : DataServiceExpressionVisitor
    {
        /// Internal buffer.
        private readonly StringBuilder builder; 

        /// Data context used to generate type names for types. 
        private readonly DataServiceContext context; 

        /// set if can't translate expression 
        private bool cantTranslateExpression;

        /// 
        /// Creates an ExpressionWriter 
        /// 
        /// Data context used to generate type names for types. 
        private ExpressionWriter(DataServiceContext context) 
        {
            Debug.Assert(context != null, "context != null"); 
            this.context = context;
            this.builder = new StringBuilder();
        }
 
        /// 
        /// Serializes an expression to a string 
        ///  
        /// Data context used to generate type names for types.
        /// Expression to serialize 
        /// serialized expression
        internal static string ExpressionToString(DataServiceContext context, Expression e)
        {
            ExpressionWriter ew = new ExpressionWriter(context); 
            string serialized = ew.Translate(e);
            if (ew.cantTranslateExpression) 
            { 
                throw new NotSupportedException(Strings.ALinq_CantTranslateExpression(e.ToString()));
            } 

            return serialized;
        }
 
        /// 
        /// ConditionalExpression visit method 
        ///  
        /// The ConditionalExpression expression to visit
        /// The visited ConditionalExpression expression  
        internal override Expression VisitConditional(ConditionalExpression c)
        {
            this.cantTranslateExpression = true;
            return c; 
        }
 
        ///  
        /// LambdaExpression visit method
        ///  
        /// The LambdaExpression to visit
        /// The visited LambdaExpression
        internal override Expression VisitLambda(LambdaExpression lambda)
        { 
            this.cantTranslateExpression = true;
            return lambda; 
        } 

        ///  
        /// NewExpression visit method
        /// 
        /// The NewExpression to visit
        /// The visited NewExpression 
        internal override NewExpression VisitNew(NewExpression nex)
        { 
            this.cantTranslateExpression = true; 
            return nex;
        } 

        /// 
        /// MemberInitExpression visit method
        ///  
        /// The MemberInitExpression to visit
        /// The visited MemberInitExpression 
        internal override Expression VisitMemberInit(MemberInitExpression init) 
        {
            this.cantTranslateExpression = true; 
            return init;
        }

        ///  
        /// ListInitExpression visit method
        ///  
        /// The ListInitExpression to visit 
        /// The visited ListInitExpression
        internal override Expression VisitListInit(ListInitExpression init) 
        {
            this.cantTranslateExpression = true;
            return init;
        } 

        ///  
        /// NewArrayExpression visit method 
        /// 
        /// The NewArrayExpression to visit 
        /// The visited NewArrayExpression
        internal override Expression VisitNewArray(NewArrayExpression na)
        {
            this.cantTranslateExpression = true; 
            return na;
        } 
 
        /// 
        /// InvocationExpression visit method 
        /// 
        /// The InvocationExpression to visit
        /// The visited InvocationExpression
        internal override Expression VisitInvocation(InvocationExpression iv) 
        {
            this.cantTranslateExpression = true; 
            return iv; 
        }
 
        /// 
        /// Input resource set references are intentionally omitted from the URL string.
        /// 
        /// The input reference 
        /// The same input reference expression
        internal override Expression VisitInputReferenceExpression(InputReferenceExpression ire) 
        { 
            // This method intentionally does not write anything to the URI.
            // This is how 'Where(.Id == 5)' becomes '$filter=Id eq 5'. 
            return ire;
        }

        ///  
        /// MethodCallExpression visit method
        ///  
        /// The MethodCallExpression expression to visit 
        /// The visited MethodCallExpression expression 
        internal override Expression VisitMethodCall(MethodCallExpression m) 
        {
            string methodName;
            if (TypeSystem.TryGetQueryOptionMethod(m.Method, out methodName))
            { 
                this.builder.Append(methodName);
                this.builder.Append(UriHelper.LEFTPAREN); 
 
                // There is a single function, 'substringof', which reorders its argument with
                // respect to the CLR method. Thus handling it as a special case rather than 
                // using a more general argument reordering mechanism.
                if (methodName == "substringof")
                {
                    Debug.Assert(m.Method.Name == "Contains", "m.Method.Name == 'Contains'"); 
                    Debug.Assert(m.Object != null, "m.Object != null");
                    Debug.Assert(m.Arguments.Count == 1, "m.Arguments.Count == 1"); 
                    this.Visit(m.Arguments[0]); 
                    this.builder.Append(UriHelper.COMMA);
                    this.Visit(m.Object); 
                }
                else
                {
                    if (m.Object != null) 
                    {
                        this.Visit(m.Object); 
                    } 

                    if (m.Arguments.Count > 0) 
                    {
                        if (m.Object != null)
                        {
                            this.builder.Append(UriHelper.COMMA); 
                        }
 
                        for (int ii = 0; ii < m.Arguments.Count; ii++) 
                        {
                            this.Visit(m.Arguments[ii]); 
                            if (ii < m.Arguments.Count - 1)
                            {
                                this.builder.Append(UriHelper.COMMA);
                            } 
                        }
                    } 
                } 

                this.builder.Append(UriHelper.RIGHTPAREN); 
            }
            else
            {
                this.cantTranslateExpression = true; 
            }
 
            return m; 
        }
 
        /// 
        /// Serializes an MemberExpression to a string
        /// 
        /// Expression to serialize 
        /// MemberExpression
        internal override Expression VisitMemberAccess(MemberExpression m) 
        { 
            if (m.Member is FieldInfo)
            { 
                throw new NotSupportedException(Strings.ALinq_CantReferToPublicField(m.Member.Name));
            }

            Expression e = this.Visit(m.Expression); 
            if (!IsInputReference(e))
            { 
                this.builder.Append(UriHelper.FORWARDSLASH); 
            }
 
            this.builder.Append(m.Member.Name);

            return m;
        } 

        ///  
        /// ConstantExpression visit method 
        /// 
        /// The ConstantExpression expression to visit 
        /// The visited ConstantExpression expression 
        internal override Expression VisitConstant(ConstantExpression c)
        {
            string result = null; 
            if (c.Value == null)
            { 
                this.builder.Append(UriHelper.NULL); 
                return c;
            } 
            else if (!ClientConvert.TryKeyPrimitiveToString(c.Value, out result))
            {
                throw new InvalidOperationException(Strings.ALinq_CouldNotConvert(c.Value));
            } 

            Debug.Assert(result != null, "result != null"); 
            this.builder.Append(result); 
            return c;
        } 

        /// 
        /// Serializes an UnaryExpression to a string
        ///  
        /// Expression to serialize
        /// UnaryExpression 
        internal override Expression VisitUnary(UnaryExpression u) 
        {
            switch (u.NodeType) 
            {
                case ExpressionType.Not:
                    this.builder.Append(UriHelper.NOT);
                    this.builder.Append(UriHelper.SPACE); 
                    this.VisitOperand(u.Operand);
                    break; 
                case ExpressionType.Negate: 
                case ExpressionType.NegateChecked:
                    this.builder.Append(UriHelper.SPACE); 
                    this.builder.Append(UriHelper.NEGATE);
                    this.VisitOperand(u.Operand);
                    break;
                case ExpressionType.Convert: 
                case ExpressionType.ConvertChecked:
                    this.builder.Append(UriHelper.CAST); 
                    this.builder.Append(UriHelper.LEFTPAREN); 
                    if (!IsInputReference(u.Operand))
                    { 
                        this.Visit(u.Operand);
                        this.builder.Append(UriHelper.COMMA);
                    }
 
                    this.builder.Append(UriHelper.QUOTE);
                    this.builder.Append(this.TypeNameForUri(u.Type)); 
                    this.builder.Append(UriHelper.QUOTE); 
                    this.builder.Append(UriHelper.RIGHTPAREN);
                    break; 
                case ExpressionType.UnaryPlus:
                    // no-op always ignore.
                    break;
                default: 
                    this.cantTranslateExpression = true;
                    break; 
            } 

            return u; 
        }

        /// 
        /// Serializes an BinaryExpression to a string 
        /// 
        /// BinaryExpression to serialize 
        /// serialized expression 
        internal override Expression VisitBinary(BinaryExpression b)
        { 
            this.VisitOperand(b.Left);
            this.builder.Append(UriHelper.SPACE);
            switch (b.NodeType)
            { 
                case ExpressionType.AndAlso:
                case ExpressionType.And: 
                    this.builder.Append(UriHelper.AND); 
                    break;
                case ExpressionType.OrElse: 
                case ExpressionType.Or:
                    this.builder.Append(UriHelper.OR);
                    break;
                case ExpressionType.Equal: 
                    this.builder.Append(UriHelper.EQ);
                    break; 
                case ExpressionType.NotEqual: 
                    this.builder.Append(UriHelper.NE);
                    break; 
                case ExpressionType.LessThan:
                    this.builder.Append(UriHelper.LT);
                    break;
                case ExpressionType.LessThanOrEqual: 
                    this.builder.Append(UriHelper.LE);
                    break; 
                case ExpressionType.GreaterThan: 
                    this.builder.Append(UriHelper.GT);
                    break; 
                case ExpressionType.GreaterThanOrEqual:
                    this.builder.Append(UriHelper.GE);
                    break;
                case ExpressionType.Add: 
                case ExpressionType.AddChecked:
                    this.builder.Append(UriHelper.ADD); 
                    break; 
                case ExpressionType.Subtract:
                case ExpressionType.SubtractChecked: 
                    this.builder.Append(UriHelper.SUB);
                    break;
                case ExpressionType.Multiply:
                case ExpressionType.MultiplyChecked: 
                    this.builder.Append(UriHelper.MUL);
                    break; 
                case ExpressionType.Divide: 
                    this.builder.Append(UriHelper.DIV);
                    break; 
                case ExpressionType.Modulo:
                    this.builder.Append(UriHelper.MOD);
                    break;
                case ExpressionType.ArrayIndex: 
                case ExpressionType.Power:
                case ExpressionType.Coalesce: 
                case ExpressionType.ExclusiveOr: 
                case ExpressionType.LeftShift:
                case ExpressionType.RightShift: 
                default:
                    this.cantTranslateExpression = true;
                    break;
            } 

            this.builder.Append(UriHelper.SPACE); 
            this.VisitOperand(b.Right); 
            return b;
        } 

        /// 
        /// Serializes an TypeBinaryExpression to a string
        ///  
        /// TypeBinaryExpression to serialize
        /// serialized expression 
        internal override Expression VisitTypeIs(TypeBinaryExpression b) 
        {
            this.builder.Append(UriHelper.ISOF); 
            this.builder.Append(UriHelper.LEFTPAREN);

            if (!IsInputReference(b.Expression))
            { 
                this.Visit(b.Expression);
                this.builder.Append(UriHelper.COMMA); 
                this.builder.Append(UriHelper.SPACE); 
            }
 
            this.builder.Append(UriHelper.QUOTE);
            this.builder.Append(this.TypeNameForUri(b.TypeOperand));
            this.builder.Append(UriHelper.QUOTE);
            this.builder.Append(UriHelper.RIGHTPAREN); 

            return b; 
        } 

        ///  
        /// ParameterExpression visit method.
        /// 
        /// The ParameterExpression expression to visit
        /// The visited ParameterExpression expression  
        internal override Expression VisitParameter(ParameterExpression p)
        { 
            return p; 
        }
 
        /// 
        /// References to the current input - the resource set - do not appear in the URL.
        /// 
        /// The expression to test 
        /// true if the expression represents a reference to the current (resource set) input; otherwise false.
        private static bool IsInputReference(Expression exp) 
        { 
            return (exp is InputReferenceExpression || exp is ParameterExpression);
        } 

        /// Gets the type name to be used in the URI for the given .
        /// Type to get name for.
        /// The name for the , suitable for including in a URI. 
        private string TypeNameForUri(Type type)
        { 
            Debug.Assert(type != null, "type != null"); 
            type = Nullable.GetUnderlyingType(type) ?? type;
 
            if (ClientConvert.IsKnownType(type))
            {
                if (ClientConvert.IsSupportedPrimitiveTypeForUri(type))
                { 
                    return ClientConvert.ToTypeName(type);
                } 
 
                // unsupported primitive type
                throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(type.Name)); 
            }
            else
            {
                return this.context.ResolveNameFromType(type) ?? type.FullName; 
            }
        } 
 
        /// 
        /// Visits operands for Binary and Unary expressions. 
        /// Will only output parens if operand is complex expression,
        /// this is so don't have unecessary parens in URI.
        /// 
        /// The operand expression to visit 
        private void VisitOperand(Expression e)
        { 
            if (e is BinaryExpression || e is UnaryExpression) 
            {
                this.builder.Append(UriHelper.LEFTPAREN); 
                this.Visit(e);
                this.builder.Append(UriHelper.RIGHTPAREN);
            }
            else 
            {
                this.Visit(e); 
            } 
        }
 
        /// 
        /// Serializes an expression to a string
        /// 
        /// Expression to serialize 
        /// serialized expression
        private string Translate(Expression e) 
        { 
            this.Visit(e);
            return this.builder.ToString(); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK