ProjectedWrapper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / Internal / ProjectedWrapper.cs / 1305376 / ProjectedWrapper.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Provides a base class implementing IProjectedResult over
//      projections. 
//  
//
// @owner  [....] 
//---------------------------------------------------------------------

namespace System.Data.Services.Internal
{ 
    using System.Collections;
    using System.Diagnostics; 
    using System.Linq; 
    using System.Linq.Expressions;
 
    /// Base class for all projected wrappers. The internal implementation of the 
    /// interface. We use this and the other ProjectedWrapper classes to project a subset of properties
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public abstract class ProjectedWrapper : IProjectedResult
    { 
        #region Fields. 
        /// Array of predefined projected wrappers for small number of properties. When we need to project
        /// more properties than these allow we will use the . 
        private static Type[] precreatedProjectedWrapperTypes = new Type[]
        {
            typeof(ProjectedWrapper0),
            typeof(ProjectedWrapper1), 
            typeof(ProjectedWrapper2),
            typeof(ProjectedWrapper3), 
            typeof(ProjectedWrapper4), 
            typeof(ProjectedWrapper5),
            typeof(ProjectedWrapper6), 
            typeof(ProjectedWrapper7),
            typeof(ProjectedWrapper8)
        };
 
        /// Array of projected propery names used for fast lookup based on the projected property index.
        private static string[] projectedPropertyNames = new string[] 
        { 
            "ProjectedProperty0",
            "ProjectedProperty1", 
            "ProjectedProperty2",
            "ProjectedProperty3",
            "ProjectedProperty4",
            "ProjectedProperty5", 
            "ProjectedProperty6",
            "ProjectedProperty7" 
        }; 

        /// The full name of the type 
        private string resourceTypeName;

        /// Text list of property names, in comma-separated format.
        /// The position of each property name determines the index of the projected property 
        /// which holds the value of that property.
        /// Some slot may be empty denoting that the projected property is not used for this instance. 
        private string propertyNameList; 

        /// Parsed list property names. 
        private string[] propertyNames;

        #endregion Fields.
 
        #region Public properties.
 
        /// The full name of the  which represents the type 
        /// of this result.
        public string ResourceTypeName 
        {
            get
            {
                return this.resourceTypeName; 
            }
 
            set 
            {
                Debug.Assert(value != null, "value != null"); 
                this.resourceTypeName = value;
            }
        }
 
        /// Text list of property names, in comma-separated format.
        public string PropertyNameList 
        { 
            get
            { 
                return this.propertyNameList;
            }

            set 
            {
                this.propertyNameList = WebUtil.CheckArgumentNull(value, "value"); 
                this.propertyNames = WebUtil.StringToSimpleArray(this.propertyNameList); 
            }
        } 

        #endregion Public properties.

        #region Methods. 

        /// Gets the value for named property for the result. 
        /// Name of property for which to get the value. 
        /// The value for the named property of the result.
        public object GetProjectedPropertyValue(string propertyName) 
        {
            WebUtil.CheckArgumentNull(propertyName, "propertyName");

            if (this.propertyNames == null) 
            {
                throw new InvalidOperationException(Strings.BasicExpandProvider_ProjectedPropertiesNotInitialized); 
            } 

            int nameIndex = -1; 
            for (int i = 0; i < this.propertyNames.Length; i++)
            {
                if (this.propertyNames[i] == propertyName)
                { 
                    nameIndex = i;
                    break; 
                } 
            }
 
            return this.InternalGetProjectedPropertyValue(nameIndex);
        }

        /// Returns the type of the  with the specified number of projected properties. 
        /// The number of properties to project in the wrapper.
        /// The type of the projected wrapper to use (note that it might have room for more properties!) 
        internal static Type GetProjectedWrapperType(int projectedPropertyCount) 
        {
            if (projectedPropertyCount < precreatedProjectedWrapperTypes.Length) 
            {
                return precreatedProjectedWrapperTypes[projectedPropertyCount];
            }
            else 
            {
                return typeof(ProjectedWrapperMany); 
            } 
        }
 
        /// Creates an array of  objects which bind the projected properties
        /// to the expressions passed in .
        /// Array of expressions to bind to properties on the projected wrapper.
        /// The expression at index 0 will be bound to the ResourceTypeName property. 
        /// The expression at index 1 will be bound to the PropertyNameList property.
        /// The expression at index 2 + i will be bound to the ith projected property. 
        /// The type of the projected wrapper to use. You should get this 
        /// by calling the  method.
        /// An array of bindings which bind the specified expression to the properties on the projected wrapper. 
        internal static MemberBinding[] Bind(Expression[] bindingExpressions, Type projectedWrapperType)
        {
            Debug.Assert(bindingExpressions != null, "bindingExpression != null");
            Debug.Assert(projectedWrapperType != null, "projectedWrapperType != null"); 
            Debug.Assert(bindingExpressions.Length >= 2, "At least the ResourceTypeName and PropertyNameList properties must be bound.");
            Debug.Assert( 
                GetProjectedWrapperType(bindingExpressions.Length - 2) == projectedWrapperType, 
                "The projected wrapper type will not fit the required number of properties.");
 
            int bindingsCount = bindingExpressions.Length;
            MemberBinding[] bindings;
            // The number of precreate types - 1 (they start with 0 properties) + ResourceTypeName + Description
            if (bindingsCount <= precreatedProjectedWrapperTypes.Length + 1) 
            {
                // The number of properties fits into a single projected wrapper instance 
                bindings = new MemberBinding[bindingsCount]; 
                BindResourceTypeAndPropertyNameList(projectedWrapperType, bindings, bindingExpressions);
                for (int propertyIndex = 0; propertyIndex < bindingsCount - 2; propertyIndex++) 
                {
                    bindings[propertyIndex + 2] = BindToProjectedProperty(
                        projectedWrapperType,
                        propertyIndex, 
                        bindingExpressions[propertyIndex + 2]);
                } 
            } 
            else
            { 
                // The number of properties is too big - we need to use the linked list of ProjectedWrapperMany instances
                // So we return the number of properties we can bind + ResourceTypeName + Description + Next
                //   the rest of the bindings will be bound to the Next
                bindings = new MemberBinding[precreatedProjectedWrapperTypes.Length + 2]; 

                // Only fill the ResourceTypeName and Description on the first ProjectedWrapperMany 
                //   the inner ones will never use it. 
                BindResourceTypeAndPropertyNameList(projectedWrapperType, bindings, bindingExpressions);
 
                // And now call the recursive method to fill the rest.
                BindToProjectedWrapperMany(bindingExpressions, 2, bindings, 2);
            }
 
            return bindings;
        } 
 
        /// If the specified resource is  this method
        /// will returned a wrapped instance which will turn all special "null" instances of ProjectedWrapper 
        /// in the enumeration results into the true null values. Otherwise this method simply
        /// returns the resource untouched.
        /// The resource to wrap.
        /// The original resource or wrapped resource if it was . 
        /// Note that we don't expect that the enumeration of results might return result
        /// which itself will be enumeration (nested enumerations). We handle this case through the 
        /// ExpandedWrapper instance instead. 
        internal static object ProcessResultEnumeration(object resource)
        { 
            IEnumerable enumerable;
            if (WebUtil.IsElementIEnumerable(resource, out enumerable))
            {
                return new EnumerableWrapper(enumerable); 
            }
            else 
            { 
                return resource;
            } 
        }

        /// Helper method which checks the specified resource and if it is the special
        /// "null" ProjectedWrapper value it will turn it into a true null. Otherwise it returns the original value. 
        /// The resource to check for nullness.
        /// The original value, or null if the value was representing null value. 
        internal static object ProcessResultInstance(object resource) 
        {
            ProjectedWrapper projectedWrapper = resource as ProjectedWrapper; 
            if (projectedWrapper != null && string.IsNullOrEmpty(projectedWrapper.resourceTypeName))
            {
                return null;
            } 
            else
            { 
                return resource; 
            }
        } 

        /// Unwraps  which might be wrapped to report null values correctly.
        /// If the input is not wrapped it returns the original enumerator.
        /// The enumerator to unwrap. 
        /// The unwrapped enumerator.
        internal static IEnumerator UnwrapEnumerator(IEnumerator enumerator) 
        { 
            EnumeratorWrapper wrapper = enumerator as EnumeratorWrapper;
            if (wrapper != null) 
            {
                enumerator = wrapper.InnerEnumerator;
            }
 
            return enumerator;
        } 
 
        /// Returns a wrapping  which will turn all special "null" instances
        /// of ProjectedWrapper in the enumeration results into true null values. 
        /// The  to wrap.
        /// Newly created wrapped for the specified .
        internal static IQueryable WrapQueryable(IQueryable queryable)
        { 
            Debug.Assert(queryable != null, "queryable != null");
            return new QueryableWrapper(queryable); 
        } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value.
        /// The value for the property.
        protected abstract object InternalGetProjectedPropertyValue(int propertyIndex);
 
        /// Binds the ResourceTypeName and PropertyNameList properties to the first two expressions.
        /// The type of the projected wrapper to bind to. 
        /// Items 0 and 1 will be filled with the bindings in this array. 
        /// The expressions to bind - only items 0 and 1 are used.
        private static void BindResourceTypeAndPropertyNameList( 
            Type projectedWrapperType,
            MemberBinding[] bindings,
            Expression[] bindingExpressions)
        { 
            Debug.Assert(bindings.Length >= 2, "Must have at least two bindings.");
            Debug.Assert(bindingExpressions.Length >= 2, "Must have at least two expressions to bind."); 
            Debug.Assert(typeof(ProjectedWrapper).IsAssignableFrom(projectedWrapperType), "Can't bind to type which is not a projected wrapper."); 

            bindings[0] = Expression.Bind(projectedWrapperType.GetProperty("ResourceTypeName"), bindingExpressions[0]); 
            bindings[1] = Expression.Bind(projectedWrapperType.GetProperty("PropertyNameList"), bindingExpressions[1]);
        }

        /// Binds specified expression to a projected propety of a given index. 
        /// The type of the projected wrapper to bind to.
        /// The index of the projected property to bind to. 
        /// The expression to bind to the property. 
        /// The newly create binding expression.
        private static MemberAssignment BindToProjectedProperty(Type projectedWrapperType, int propertyIndex, Expression expression) 
        {
            Debug.Assert(
                typeof(ProjectedWrapper).IsAssignableFrom(projectedWrapperType),
                "Trying to bind to a type which is not a projected wrapper."); 
            Debug.Assert(
                propertyIndex < projectedPropertyNames.Length, 
                "Trying to bind to a too big property index."); 

            return Expression.Bind( 
                projectedWrapperType.GetProperty(projectedPropertyNames[propertyIndex]),
                expression);
        }
 
        /// Binds projected epxressions to the  object.
        /// Array of expressions to bind. 
        /// Index of the first expression in the  to bind. 
        /// Array to fill with the bindings.
        /// Index of the first slot in  to fill. 
        private static void BindToProjectedWrapperMany(
            Expression[] bindingExpressions,
            int expressionStartIndex,
            MemberBinding[] bindings, 
            int bindingStartIndex)
        { 
            Debug.Assert( 
                bindings.Length - bindingStartIndex == precreatedProjectedWrapperTypes.Length,
                "We need space in the bindings to bind all the properties."); 
            Debug.Assert(bindingExpressions.Length > expressionStartIndex, "At least one expression to bind.");

            int propertyIndex = 0;
            for (; propertyIndex < precreatedProjectedWrapperTypes.Length - 1 && propertyIndex + expressionStartIndex < bindingExpressions.Length; propertyIndex++) 
            {
                bindings[bindingStartIndex + propertyIndex] = BindToProjectedProperty( 
                    typeof(ProjectedWrapperMany), 
                    propertyIndex,
                    bindingExpressions[expressionStartIndex + propertyIndex]); 
            }

            if (bindingExpressions.Length > precreatedProjectedWrapperTypes.Length - 1 + expressionStartIndex)
            { 
                int nextCount = bindingExpressions.Length - (precreatedProjectedWrapperTypes.Length - 1 + expressionStartIndex);
                if (nextCount > precreatedProjectedWrapperTypes.Length - 1) 
                { 
                    // If we're not going to fit into the next wrapper, we need one more for the Next property
                    nextCount = precreatedProjectedWrapperTypes.Length; 
                }

                // We need more still - so create the next link on the Next property
                MemberBinding[] nextBindings = new MemberBinding[precreatedProjectedWrapperTypes.Length + 2]; 
                nextBindings[0] = Expression.Bind(
                    typeof(ProjectedWrapperMany).GetProperty("ResourceTypeName"), 
                    Expression.Constant(string.Empty, typeof(string))); 
                nextBindings[1] = Expression.Bind(
                    typeof(ProjectedWrapperMany).GetProperty("PropertyNameList"), 
                    Expression.Constant(string.Empty, typeof(string)));
                BindToProjectedWrapperMany(
                    bindingExpressions,
                    expressionStartIndex + precreatedProjectedWrapperTypes.Length - 1, 
                    nextBindings,
                    2); 
                Expression restProjectedWrapper = Expression.MemberInit( 
                    Expression.New(typeof(ProjectedWrapperMany)),
                    nextBindings); 
                bindings[bindingStartIndex + precreatedProjectedWrapperTypes.Length - 1] = Expression.Bind(
                    typeof(ProjectedWrapperMany).GetProperty("Next"),
                    restProjectedWrapper);
            } 
            else
            { 
                // This is the last one. We need to project something to the remaining properties 
                //   and then the special End instance to the Next property.
                //   This is necessary to make Linq to Entities work as it fails when the same type is initialized 
                //   multiple times in the same query and the initializions don't set the same properties in the same order.
                for (; propertyIndex < precreatedProjectedWrapperTypes.Length - 1; propertyIndex++)
                {
                    // Project empty strings for example (as they are very likely to easily round trip through and query system) 
                    bindings[bindingStartIndex + propertyIndex] = BindToProjectedProperty(
                            typeof(ProjectedWrapperMany), 
                            propertyIndex, 
                            Expression.Constant(string.Empty, typeof(string)));
                } 

                // And then project the special End instance to the Next property
                //   we need to project something into the Next property, but we can't project ProjectedWrapperMany
                //   as Linq to Entities would require us to initialize all its properties (and thus we would end up in infinite loop). 
                // Instead it is OK to project a different type (Since we never projected that one in this query yet).
                // Note that we need to initialize at least one property on the special type to avoid a problem 
                // in Linq to Entities where it might fails with null-ref exception. 
                bindings[bindingStartIndex + precreatedProjectedWrapperTypes.Length - 1] = Expression.Bind(
                    typeof(ProjectedWrapperMany).GetProperty("Next"), 
                    Expression.MemberInit(
                        Expression.New(typeof(ProjectedWrapperManyEnd)),
                        Expression.Bind(
                            typeof(ProjectedWrapperManyEnd).GetProperty("ResourceTypeName"), 
                            Expression.Constant(string.Empty, typeof(string)))));
            } 
        } 

        #endregion Methods. 

        #region Enumeration wrappers
        /// Wrapper around  which replaces special "null" instances
        /// of ProjectedWrapper in the results with true null values. 
        private sealed class QueryableWrapper : EnumerableWrapper, IQueryable
        { 
            /// The  this object is wrapping. 
            private readonly IQueryable queryable;
 
            /// Constructor.
            /// The queryable to wrap.
            internal QueryableWrapper(IQueryable queryable) : base(queryable)
            { 
                Debug.Assert(queryable != null, "queryable != null");
                this.queryable = queryable; 
            } 

            /// The type of the single element which is returned as a result of the query. 
            public Type ElementType
            {
                get { return this.queryable.ElementType; }
            } 

            /// The expression tree for this query. 
            public Expression Expression 
            {
                get { return this.queryable.Expression; } 
            }

            /// The query provider - not support as it should never be called.
            public IQueryProvider Provider 
            {
                get { throw Error.NotSupported(); } 
            } 
        }
 
        /// Wrapper around  which replaces special "null" instances
        /// of ProjectedWrapper in the results with true null values.
        private class EnumerableWrapper : IEnumerable
        { 
            /// The  this object is wrapping.
            private readonly IEnumerable enumerable; 
 
            /// Constructor.
            /// The enumerable to wrap. 
            internal EnumerableWrapper(IEnumerable enumerable)
            {
                Debug.Assert(enumerable != null, "enumerable != null");
                this.enumerable = enumerable; 
            }
 
            /// Gets a new enumerator. 
            /// The newly created .
            IEnumerator IEnumerable.GetEnumerator() 
            {
                return this.GetEnumerator();
            }
 
            /// Gets a new enumerator.
            /// The newly created . 
            public IEnumerator GetEnumerator() 
            {
                return new EnumeratorWrapper(this.enumerable.GetEnumerator()); 
            }
        }

        /// Wrapper around  which replaces special "null" instances 
        /// of ProjectedWrapper in the results with true null values.
        private sealed class EnumeratorWrapper : IEnumerator, IDisposable 
        { 
            /// The  this object is wrapping.
            private readonly IEnumerator enumerator; 

            /// Constructor.
            /// The enumerator to wrap.
            internal EnumeratorWrapper(IEnumerator enumerator) 
            {
                Debug.Assert(enumerator != null, "enumerator != null"); 
                this.enumerator = enumerator; 
            }
 
            /// Returns the current result on which the enumerator is positioned.
            public object Current
            {
                get { return ProjectedWrapper.ProcessResultInstance(this.enumerator.Current); } 
            }
 
            /// Returns the inner enumerator thic object is wrapping. 
            internal IEnumerator InnerEnumerator
            { 
                get { return this.enumerator; }
            }

            /// Moves the enumerator to the next result. 
            /// true if next result is available, false otherwise.
            public bool MoveNext() 
            { 
                return this.enumerator.MoveNext();
            } 

            /// Resets the enumerator.
            public void Reset()
            { 
                this.enumerator.Reset();
            } 
 
            /// Disposes the object.
            public void Dispose() 
            {
                WebUtil.Dispose(this.enumerator);
            }
        } 
        #endregion
    } 
 
    /// Provides a wrapper over result element with the ability to project a subset of properties.
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper0 : ProjectedWrapper
    {
        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value.
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            throw Error.NotSupported(); 
        }
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public sealed class ProjectedWrapper1 : ProjectedWrapper 
    {
        /// Gets or sets a projected property. 
        public object ProjectedProperty0 { get; set; }

        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        { 
            if (propertyIndex == 0) return this.ProjectedProperty0;
            throw Error.NotSupported(); 
        }
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public sealed class ProjectedWrapper2 : ProjectedWrapper 
    {
        /// Gets or sets a projected property. 
        public object ProjectedProperty0 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                default: 
                   throw Error.NotSupported(); 
            }
        } 
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties.
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper3 : ProjectedWrapper 
    { 
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; } 
 
        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex)
        {
            switch (propertyIndex) 
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1; 
                case 2: return this.ProjectedProperty2;
                default: 
                    throw Error.NotSupported();
            }
        }
    } 

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper4 : ProjectedWrapper 
    {
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty3 { get; set; }
 
        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value. 
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex)
        { 
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0;
                case 1: return this.ProjectedProperty1; 
                case 2: return this.ProjectedProperty2;
                case 3: return this.ProjectedProperty3; 
                default: 
                    throw Error.NotSupported();
            } 
        }
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public sealed class ProjectedWrapper5 : ProjectedWrapper 
    {
        /// Gets or sets a projected property. 
        public object ProjectedProperty0 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty2 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty3 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2; 
                case 3: return this.ProjectedProperty3; 
                case 4: return this.ProjectedProperty4;
                default: 
                    throw Error.NotSupported();
            }
        }
    } 

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper6 : ProjectedWrapper 
    {
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty3 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty5 { get; set; } 

        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value.
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex)
        { 
            switch (propertyIndex) 
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2;
                case 3: return this.ProjectedProperty3;
                case 4: return this.ProjectedProperty4; 
                case 5: return this.ProjectedProperty5;
                default: 
                    throw Error.NotSupported(); 
            }
        } 
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties.
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper7 : ProjectedWrapper 
    { 
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty3 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty5 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty6 { get; set; } 

        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value.
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex)
        { 
            switch (propertyIndex) 
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2;
                case 3: return this.ProjectedProperty3;
                case 4: return this.ProjectedProperty4; 
                case 5: return this.ProjectedProperty5;
                case 6: return this.ProjectedProperty6; 
                default: 
                    throw Error.NotSupported();
            } 
        }
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public sealed class ProjectedWrapper8 : ProjectedWrapper 
    {
        /// Gets or sets a projected property. 
        public object ProjectedProperty0 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty2 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty3 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty5 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty6 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty7 { get; set; } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2; 
                case 3: return this.ProjectedProperty3; 
                case 4: return this.ProjectedProperty4;
                case 5: return this.ProjectedProperty5; 
                case 6: return this.ProjectedProperty6;
                case 7: return this.ProjectedProperty7;
                default:
                    throw Error.NotSupported(); 
            }
        } 
    } 

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public class ProjectedWrapperMany : ProjectedWrapper
    { 
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty3 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty5 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty6 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty7 { get; set; } 

        /// Gets or sets another instance of  which contains the set
        /// of next 8 projected properties (and potentially another link).
        public ProjectedWrapperMany Next { get; set; } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2; 
                case 3: return this.ProjectedProperty3; 
                case 4: return this.ProjectedProperty4;
                case 5: return this.ProjectedProperty5; 
                case 6: return this.ProjectedProperty6;
                case 7: return this.ProjectedProperty7;
                default:
                    if (this.Next == null || propertyIndex < 0) 
                    {
                        throw Error.NotSupported(); 
                    } 
                    else
                    { 
                        return this.Next.InternalGetProjectedPropertyValue(propertyIndex - 8);
                    }
            }
        } 
    }
 
    /// Instance of this class is assigned to the last  in the list. 
    /// This trick is necessary for Entity Framework to work correctly, as it can't project null into the Next property.
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapperManyEnd : ProjectedWrapperMany
    {
        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value.
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            // We should never get here - no properties are projected into this class (ever). 
            throw Error.NotSupported();
        }
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Provides a base class implementing IProjectedResult over
//      projections. 
//  
//
// @owner  [....] 
//---------------------------------------------------------------------

namespace System.Data.Services.Internal
{ 
    using System.Collections;
    using System.Diagnostics; 
    using System.Linq; 
    using System.Linq.Expressions;
 
    /// Base class for all projected wrappers. The internal implementation of the 
    /// interface. We use this and the other ProjectedWrapper classes to project a subset of properties
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public abstract class ProjectedWrapper : IProjectedResult
    { 
        #region Fields. 
        /// Array of predefined projected wrappers for small number of properties. When we need to project
        /// more properties than these allow we will use the . 
        private static Type[] precreatedProjectedWrapperTypes = new Type[]
        {
            typeof(ProjectedWrapper0),
            typeof(ProjectedWrapper1), 
            typeof(ProjectedWrapper2),
            typeof(ProjectedWrapper3), 
            typeof(ProjectedWrapper4), 
            typeof(ProjectedWrapper5),
            typeof(ProjectedWrapper6), 
            typeof(ProjectedWrapper7),
            typeof(ProjectedWrapper8)
        };
 
        /// Array of projected propery names used for fast lookup based on the projected property index.
        private static string[] projectedPropertyNames = new string[] 
        { 
            "ProjectedProperty0",
            "ProjectedProperty1", 
            "ProjectedProperty2",
            "ProjectedProperty3",
            "ProjectedProperty4",
            "ProjectedProperty5", 
            "ProjectedProperty6",
            "ProjectedProperty7" 
        }; 

        /// The full name of the type 
        private string resourceTypeName;

        /// Text list of property names, in comma-separated format.
        /// The position of each property name determines the index of the projected property 
        /// which holds the value of that property.
        /// Some slot may be empty denoting that the projected property is not used for this instance. 
        private string propertyNameList; 

        /// Parsed list property names. 
        private string[] propertyNames;

        #endregion Fields.
 
        #region Public properties.
 
        /// The full name of the  which represents the type 
        /// of this result.
        public string ResourceTypeName 
        {
            get
            {
                return this.resourceTypeName; 
            }
 
            set 
            {
                Debug.Assert(value != null, "value != null"); 
                this.resourceTypeName = value;
            }
        }
 
        /// Text list of property names, in comma-separated format.
        public string PropertyNameList 
        { 
            get
            { 
                return this.propertyNameList;
            }

            set 
            {
                this.propertyNameList = WebUtil.CheckArgumentNull(value, "value"); 
                this.propertyNames = WebUtil.StringToSimpleArray(this.propertyNameList); 
            }
        } 

        #endregion Public properties.

        #region Methods. 

        /// Gets the value for named property for the result. 
        /// Name of property for which to get the value. 
        /// The value for the named property of the result.
        public object GetProjectedPropertyValue(string propertyName) 
        {
            WebUtil.CheckArgumentNull(propertyName, "propertyName");

            if (this.propertyNames == null) 
            {
                throw new InvalidOperationException(Strings.BasicExpandProvider_ProjectedPropertiesNotInitialized); 
            } 

            int nameIndex = -1; 
            for (int i = 0; i < this.propertyNames.Length; i++)
            {
                if (this.propertyNames[i] == propertyName)
                { 
                    nameIndex = i;
                    break; 
                } 
            }
 
            return this.InternalGetProjectedPropertyValue(nameIndex);
        }

        /// Returns the type of the  with the specified number of projected properties. 
        /// The number of properties to project in the wrapper.
        /// The type of the projected wrapper to use (note that it might have room for more properties!) 
        internal static Type GetProjectedWrapperType(int projectedPropertyCount) 
        {
            if (projectedPropertyCount < precreatedProjectedWrapperTypes.Length) 
            {
                return precreatedProjectedWrapperTypes[projectedPropertyCount];
            }
            else 
            {
                return typeof(ProjectedWrapperMany); 
            } 
        }
 
        /// Creates an array of  objects which bind the projected properties
        /// to the expressions passed in .
        /// Array of expressions to bind to properties on the projected wrapper.
        /// The expression at index 0 will be bound to the ResourceTypeName property. 
        /// The expression at index 1 will be bound to the PropertyNameList property.
        /// The expression at index 2 + i will be bound to the ith projected property. 
        /// The type of the projected wrapper to use. You should get this 
        /// by calling the  method.
        /// An array of bindings which bind the specified expression to the properties on the projected wrapper. 
        internal static MemberBinding[] Bind(Expression[] bindingExpressions, Type projectedWrapperType)
        {
            Debug.Assert(bindingExpressions != null, "bindingExpression != null");
            Debug.Assert(projectedWrapperType != null, "projectedWrapperType != null"); 
            Debug.Assert(bindingExpressions.Length >= 2, "At least the ResourceTypeName and PropertyNameList properties must be bound.");
            Debug.Assert( 
                GetProjectedWrapperType(bindingExpressions.Length - 2) == projectedWrapperType, 
                "The projected wrapper type will not fit the required number of properties.");
 
            int bindingsCount = bindingExpressions.Length;
            MemberBinding[] bindings;
            // The number of precreate types - 1 (they start with 0 properties) + ResourceTypeName + Description
            if (bindingsCount <= precreatedProjectedWrapperTypes.Length + 1) 
            {
                // The number of properties fits into a single projected wrapper instance 
                bindings = new MemberBinding[bindingsCount]; 
                BindResourceTypeAndPropertyNameList(projectedWrapperType, bindings, bindingExpressions);
                for (int propertyIndex = 0; propertyIndex < bindingsCount - 2; propertyIndex++) 
                {
                    bindings[propertyIndex + 2] = BindToProjectedProperty(
                        projectedWrapperType,
                        propertyIndex, 
                        bindingExpressions[propertyIndex + 2]);
                } 
            } 
            else
            { 
                // The number of properties is too big - we need to use the linked list of ProjectedWrapperMany instances
                // So we return the number of properties we can bind + ResourceTypeName + Description + Next
                //   the rest of the bindings will be bound to the Next
                bindings = new MemberBinding[precreatedProjectedWrapperTypes.Length + 2]; 

                // Only fill the ResourceTypeName and Description on the first ProjectedWrapperMany 
                //   the inner ones will never use it. 
                BindResourceTypeAndPropertyNameList(projectedWrapperType, bindings, bindingExpressions);
 
                // And now call the recursive method to fill the rest.
                BindToProjectedWrapperMany(bindingExpressions, 2, bindings, 2);
            }
 
            return bindings;
        } 
 
        /// If the specified resource is  this method
        /// will returned a wrapped instance which will turn all special "null" instances of ProjectedWrapper 
        /// in the enumeration results into the true null values. Otherwise this method simply
        /// returns the resource untouched.
        /// The resource to wrap.
        /// The original resource or wrapped resource if it was . 
        /// Note that we don't expect that the enumeration of results might return result
        /// which itself will be enumeration (nested enumerations). We handle this case through the 
        /// ExpandedWrapper instance instead. 
        internal static object ProcessResultEnumeration(object resource)
        { 
            IEnumerable enumerable;
            if (WebUtil.IsElementIEnumerable(resource, out enumerable))
            {
                return new EnumerableWrapper(enumerable); 
            }
            else 
            { 
                return resource;
            } 
        }

        /// Helper method which checks the specified resource and if it is the special
        /// "null" ProjectedWrapper value it will turn it into a true null. Otherwise it returns the original value. 
        /// The resource to check for nullness.
        /// The original value, or null if the value was representing null value. 
        internal static object ProcessResultInstance(object resource) 
        {
            ProjectedWrapper projectedWrapper = resource as ProjectedWrapper; 
            if (projectedWrapper != null && string.IsNullOrEmpty(projectedWrapper.resourceTypeName))
            {
                return null;
            } 
            else
            { 
                return resource; 
            }
        } 

        /// Unwraps  which might be wrapped to report null values correctly.
        /// If the input is not wrapped it returns the original enumerator.
        /// The enumerator to unwrap. 
        /// The unwrapped enumerator.
        internal static IEnumerator UnwrapEnumerator(IEnumerator enumerator) 
        { 
            EnumeratorWrapper wrapper = enumerator as EnumeratorWrapper;
            if (wrapper != null) 
            {
                enumerator = wrapper.InnerEnumerator;
            }
 
            return enumerator;
        } 
 
        /// Returns a wrapping  which will turn all special "null" instances
        /// of ProjectedWrapper in the enumeration results into true null values. 
        /// The  to wrap.
        /// Newly created wrapped for the specified .
        internal static IQueryable WrapQueryable(IQueryable queryable)
        { 
            Debug.Assert(queryable != null, "queryable != null");
            return new QueryableWrapper(queryable); 
        } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value.
        /// The value for the property.
        protected abstract object InternalGetProjectedPropertyValue(int propertyIndex);
 
        /// Binds the ResourceTypeName and PropertyNameList properties to the first two expressions.
        /// The type of the projected wrapper to bind to. 
        /// Items 0 and 1 will be filled with the bindings in this array. 
        /// The expressions to bind - only items 0 and 1 are used.
        private static void BindResourceTypeAndPropertyNameList( 
            Type projectedWrapperType,
            MemberBinding[] bindings,
            Expression[] bindingExpressions)
        { 
            Debug.Assert(bindings.Length >= 2, "Must have at least two bindings.");
            Debug.Assert(bindingExpressions.Length >= 2, "Must have at least two expressions to bind."); 
            Debug.Assert(typeof(ProjectedWrapper).IsAssignableFrom(projectedWrapperType), "Can't bind to type which is not a projected wrapper."); 

            bindings[0] = Expression.Bind(projectedWrapperType.GetProperty("ResourceTypeName"), bindingExpressions[0]); 
            bindings[1] = Expression.Bind(projectedWrapperType.GetProperty("PropertyNameList"), bindingExpressions[1]);
        }

        /// Binds specified expression to a projected propety of a given index. 
        /// The type of the projected wrapper to bind to.
        /// The index of the projected property to bind to. 
        /// The expression to bind to the property. 
        /// The newly create binding expression.
        private static MemberAssignment BindToProjectedProperty(Type projectedWrapperType, int propertyIndex, Expression expression) 
        {
            Debug.Assert(
                typeof(ProjectedWrapper).IsAssignableFrom(projectedWrapperType),
                "Trying to bind to a type which is not a projected wrapper."); 
            Debug.Assert(
                propertyIndex < projectedPropertyNames.Length, 
                "Trying to bind to a too big property index."); 

            return Expression.Bind( 
                projectedWrapperType.GetProperty(projectedPropertyNames[propertyIndex]),
                expression);
        }
 
        /// Binds projected epxressions to the  object.
        /// Array of expressions to bind. 
        /// Index of the first expression in the  to bind. 
        /// Array to fill with the bindings.
        /// Index of the first slot in  to fill. 
        private static void BindToProjectedWrapperMany(
            Expression[] bindingExpressions,
            int expressionStartIndex,
            MemberBinding[] bindings, 
            int bindingStartIndex)
        { 
            Debug.Assert( 
                bindings.Length - bindingStartIndex == precreatedProjectedWrapperTypes.Length,
                "We need space in the bindings to bind all the properties."); 
            Debug.Assert(bindingExpressions.Length > expressionStartIndex, "At least one expression to bind.");

            int propertyIndex = 0;
            for (; propertyIndex < precreatedProjectedWrapperTypes.Length - 1 && propertyIndex + expressionStartIndex < bindingExpressions.Length; propertyIndex++) 
            {
                bindings[bindingStartIndex + propertyIndex] = BindToProjectedProperty( 
                    typeof(ProjectedWrapperMany), 
                    propertyIndex,
                    bindingExpressions[expressionStartIndex + propertyIndex]); 
            }

            if (bindingExpressions.Length > precreatedProjectedWrapperTypes.Length - 1 + expressionStartIndex)
            { 
                int nextCount = bindingExpressions.Length - (precreatedProjectedWrapperTypes.Length - 1 + expressionStartIndex);
                if (nextCount > precreatedProjectedWrapperTypes.Length - 1) 
                { 
                    // If we're not going to fit into the next wrapper, we need one more for the Next property
                    nextCount = precreatedProjectedWrapperTypes.Length; 
                }

                // We need more still - so create the next link on the Next property
                MemberBinding[] nextBindings = new MemberBinding[precreatedProjectedWrapperTypes.Length + 2]; 
                nextBindings[0] = Expression.Bind(
                    typeof(ProjectedWrapperMany).GetProperty("ResourceTypeName"), 
                    Expression.Constant(string.Empty, typeof(string))); 
                nextBindings[1] = Expression.Bind(
                    typeof(ProjectedWrapperMany).GetProperty("PropertyNameList"), 
                    Expression.Constant(string.Empty, typeof(string)));
                BindToProjectedWrapperMany(
                    bindingExpressions,
                    expressionStartIndex + precreatedProjectedWrapperTypes.Length - 1, 
                    nextBindings,
                    2); 
                Expression restProjectedWrapper = Expression.MemberInit( 
                    Expression.New(typeof(ProjectedWrapperMany)),
                    nextBindings); 
                bindings[bindingStartIndex + precreatedProjectedWrapperTypes.Length - 1] = Expression.Bind(
                    typeof(ProjectedWrapperMany).GetProperty("Next"),
                    restProjectedWrapper);
            } 
            else
            { 
                // This is the last one. We need to project something to the remaining properties 
                //   and then the special End instance to the Next property.
                //   This is necessary to make Linq to Entities work as it fails when the same type is initialized 
                //   multiple times in the same query and the initializions don't set the same properties in the same order.
                for (; propertyIndex < precreatedProjectedWrapperTypes.Length - 1; propertyIndex++)
                {
                    // Project empty strings for example (as they are very likely to easily round trip through and query system) 
                    bindings[bindingStartIndex + propertyIndex] = BindToProjectedProperty(
                            typeof(ProjectedWrapperMany), 
                            propertyIndex, 
                            Expression.Constant(string.Empty, typeof(string)));
                } 

                // And then project the special End instance to the Next property
                //   we need to project something into the Next property, but we can't project ProjectedWrapperMany
                //   as Linq to Entities would require us to initialize all its properties (and thus we would end up in infinite loop). 
                // Instead it is OK to project a different type (Since we never projected that one in this query yet).
                // Note that we need to initialize at least one property on the special type to avoid a problem 
                // in Linq to Entities where it might fails with null-ref exception. 
                bindings[bindingStartIndex + precreatedProjectedWrapperTypes.Length - 1] = Expression.Bind(
                    typeof(ProjectedWrapperMany).GetProperty("Next"), 
                    Expression.MemberInit(
                        Expression.New(typeof(ProjectedWrapperManyEnd)),
                        Expression.Bind(
                            typeof(ProjectedWrapperManyEnd).GetProperty("ResourceTypeName"), 
                            Expression.Constant(string.Empty, typeof(string)))));
            } 
        } 

        #endregion Methods. 

        #region Enumeration wrappers
        /// Wrapper around  which replaces special "null" instances
        /// of ProjectedWrapper in the results with true null values. 
        private sealed class QueryableWrapper : EnumerableWrapper, IQueryable
        { 
            /// The  this object is wrapping. 
            private readonly IQueryable queryable;
 
            /// Constructor.
            /// The queryable to wrap.
            internal QueryableWrapper(IQueryable queryable) : base(queryable)
            { 
                Debug.Assert(queryable != null, "queryable != null");
                this.queryable = queryable; 
            } 

            /// The type of the single element which is returned as a result of the query. 
            public Type ElementType
            {
                get { return this.queryable.ElementType; }
            } 

            /// The expression tree for this query. 
            public Expression Expression 
            {
                get { return this.queryable.Expression; } 
            }

            /// The query provider - not support as it should never be called.
            public IQueryProvider Provider 
            {
                get { throw Error.NotSupported(); } 
            } 
        }
 
        /// Wrapper around  which replaces special "null" instances
        /// of ProjectedWrapper in the results with true null values.
        private class EnumerableWrapper : IEnumerable
        { 
            /// The  this object is wrapping.
            private readonly IEnumerable enumerable; 
 
            /// Constructor.
            /// The enumerable to wrap. 
            internal EnumerableWrapper(IEnumerable enumerable)
            {
                Debug.Assert(enumerable != null, "enumerable != null");
                this.enumerable = enumerable; 
            }
 
            /// Gets a new enumerator. 
            /// The newly created .
            IEnumerator IEnumerable.GetEnumerator() 
            {
                return this.GetEnumerator();
            }
 
            /// Gets a new enumerator.
            /// The newly created . 
            public IEnumerator GetEnumerator() 
            {
                return new EnumeratorWrapper(this.enumerable.GetEnumerator()); 
            }
        }

        /// Wrapper around  which replaces special "null" instances 
        /// of ProjectedWrapper in the results with true null values.
        private sealed class EnumeratorWrapper : IEnumerator, IDisposable 
        { 
            /// The  this object is wrapping.
            private readonly IEnumerator enumerator; 

            /// Constructor.
            /// The enumerator to wrap.
            internal EnumeratorWrapper(IEnumerator enumerator) 
            {
                Debug.Assert(enumerator != null, "enumerator != null"); 
                this.enumerator = enumerator; 
            }
 
            /// Returns the current result on which the enumerator is positioned.
            public object Current
            {
                get { return ProjectedWrapper.ProcessResultInstance(this.enumerator.Current); } 
            }
 
            /// Returns the inner enumerator thic object is wrapping. 
            internal IEnumerator InnerEnumerator
            { 
                get { return this.enumerator; }
            }

            /// Moves the enumerator to the next result. 
            /// true if next result is available, false otherwise.
            public bool MoveNext() 
            { 
                return this.enumerator.MoveNext();
            } 

            /// Resets the enumerator.
            public void Reset()
            { 
                this.enumerator.Reset();
            } 
 
            /// Disposes the object.
            public void Dispose() 
            {
                WebUtil.Dispose(this.enumerator);
            }
        } 
        #endregion
    } 
 
    /// Provides a wrapper over result element with the ability to project a subset of properties.
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper0 : ProjectedWrapper
    {
        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value.
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            throw Error.NotSupported(); 
        }
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public sealed class ProjectedWrapper1 : ProjectedWrapper 
    {
        /// Gets or sets a projected property. 
        public object ProjectedProperty0 { get; set; }

        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        { 
            if (propertyIndex == 0) return this.ProjectedProperty0;
            throw Error.NotSupported(); 
        }
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public sealed class ProjectedWrapper2 : ProjectedWrapper 
    {
        /// Gets or sets a projected property. 
        public object ProjectedProperty0 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                default: 
                   throw Error.NotSupported(); 
            }
        } 
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties.
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper3 : ProjectedWrapper 
    { 
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; } 
 
        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex)
        {
            switch (propertyIndex) 
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1; 
                case 2: return this.ProjectedProperty2;
                default: 
                    throw Error.NotSupported();
            }
        }
    } 

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper4 : ProjectedWrapper 
    {
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty3 { get; set; }
 
        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value. 
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex)
        { 
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0;
                case 1: return this.ProjectedProperty1; 
                case 2: return this.ProjectedProperty2;
                case 3: return this.ProjectedProperty3; 
                default: 
                    throw Error.NotSupported();
            } 
        }
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public sealed class ProjectedWrapper5 : ProjectedWrapper 
    {
        /// Gets or sets a projected property. 
        public object ProjectedProperty0 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty2 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty3 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2; 
                case 3: return this.ProjectedProperty3; 
                case 4: return this.ProjectedProperty4;
                default: 
                    throw Error.NotSupported();
            }
        }
    } 

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper6 : ProjectedWrapper 
    {
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty3 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty5 { get; set; } 

        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value.
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex)
        { 
            switch (propertyIndex) 
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2;
                case 3: return this.ProjectedProperty3;
                case 4: return this.ProjectedProperty4; 
                case 5: return this.ProjectedProperty5;
                default: 
                    throw Error.NotSupported(); 
            }
        } 
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties.
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapper7 : ProjectedWrapper 
    { 
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty3 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty5 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty6 { get; set; } 

        /// Gets the value for the property specified by its index.
        /// Index of the property for which to get the value.
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex)
        { 
            switch (propertyIndex) 
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2;
                case 3: return this.ProjectedProperty3;
                case 4: return this.ProjectedProperty4; 
                case 5: return this.ProjectedProperty5;
                case 6: return this.ProjectedProperty6; 
                default: 
                    throw Error.NotSupported();
            } 
        }
    }

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] 
    public sealed class ProjectedWrapper8 : ProjectedWrapper 
    {
        /// Gets or sets a projected property. 
        public object ProjectedProperty0 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty2 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty3 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty5 { get; set; } 

        /// Gets or sets a projected property. 
        public object ProjectedProperty6 { get; set; }

        /// Gets or sets a projected property.
        public object ProjectedProperty7 { get; set; } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2; 
                case 3: return this.ProjectedProperty3; 
                case 4: return this.ProjectedProperty4;
                case 5: return this.ProjectedProperty5; 
                case 6: return this.ProjectedProperty6;
                case 7: return this.ProjectedProperty7;
                default:
                    throw Error.NotSupported(); 
            }
        } 
    } 

    /// Provides a wrapper over result element with the ability to project a subset of properties. 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public class ProjectedWrapperMany : ProjectedWrapper
    { 
        /// Gets or sets a projected property.
        public object ProjectedProperty0 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty1 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty2 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty3 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty4 { get; set; } 

        /// Gets or sets a projected property.
        public object ProjectedProperty5 { get; set; }
 
        /// Gets or sets a projected property.
        public object ProjectedProperty6 { get; set; } 
 
        /// Gets or sets a projected property.
        public object ProjectedProperty7 { get; set; } 

        /// Gets or sets another instance of  which contains the set
        /// of next 8 projected properties (and potentially another link).
        public ProjectedWrapperMany Next { get; set; } 

        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value. 
        /// The value for the property.
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            switch (propertyIndex)
            {
                case 0: return this.ProjectedProperty0; 
                case 1: return this.ProjectedProperty1;
                case 2: return this.ProjectedProperty2; 
                case 3: return this.ProjectedProperty3; 
                case 4: return this.ProjectedProperty4;
                case 5: return this.ProjectedProperty5; 
                case 6: return this.ProjectedProperty6;
                case 7: return this.ProjectedProperty7;
                default:
                    if (this.Next == null || propertyIndex < 0) 
                    {
                        throw Error.NotSupported(); 
                    } 
                    else
                    { 
                        return this.Next.InternalGetProjectedPropertyValue(propertyIndex - 8);
                    }
            }
        } 
    }
 
    /// Instance of this class is assigned to the last  in the list. 
    /// This trick is necessary for Entity Framework to work correctly, as it can't project null into the Next property.
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.MSInternal", "CA903", Justification = "Type is already under System namespace.")] 
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public sealed class ProjectedWrapperManyEnd : ProjectedWrapperMany
    {
        /// Gets the value for the property specified by its index. 
        /// Index of the property for which to get the value.
        /// The value for the property. 
        protected override object InternalGetProjectedPropertyValue(int propertyIndex) 
        {
            // We should never get here - no properties are projected into this class (ever). 
            throw Error.NotSupported();
        }
    }
} 


// 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