EnumerableValidator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / ExpressionBuilder / Internal / EnumerableValidator.cs / 1305376 / EnumerableValidator.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Collections.Generic; 
using System.Diagnostics;
using System.Globalization;

using System.Data.Metadata.Edm; // for TypeHelpers 
using System.Data.Common.CommandTrees;
 
using System.Data.Common; 
using System.Data.Common.CommandTrees.Internal;
using System.Linq; 
using System.Data.Common.Utils;

namespace System.Data.Common.CommandTrees.ExpressionBuilder.Internal
{ 
    /// 
    /// Validates an input enumerable argument with a specific element type, 
    /// converting each input element into an instance of a specific output element type, 
    /// then producing a final result of another specific type.
    ///  
    /// The element type of the input enumerable
    /// The element type that input elements are converted to
    /// The type of the final result
    internal sealed class EnumerableValidator 
    {
        private readonly string argumentName; 
        private readonly IEnumerable target; 

        internal EnumerableValidator(IEnumerable argument, string argumentName) 
        {
            this.argumentName = argumentName;
            this.target = argument;
        } 

        private bool allowEmpty; 
        private int expectedElementCount = -1; 
        private Func map;
        private Func, TResult> collect; 
        private Func deriveName;

        /// 
        /// Gets or sets a value that determines whether an exception is thrown if the enumerable argument is empty. 
        /// 
        ///  
        /// AllowEmpty is ignored if  is set. 
        /// If ExpectedElementCount is set to zero, an empty collection will not cause an exception to be thrown,
        /// even if AllowEmpty is set to false. 
        /// 
        public bool AllowEmpty { get { return this.allowEmpty; } set { this.allowEmpty = value; } }

        ///  
        /// Gets or set a value that determines the number of elements expected in the enumerable argument.
        /// A value of -1 indicates that any number of elements is permitted, including zero. 
        /// Use  to disallow an empty list when ExpectedElementCount is set to -1. 
        /// 
        public int ExpectedElementCount { get { return this.expectedElementCount; } set { this.expectedElementCount = value; } } 

        /// 
        /// Gets or sets the function used to convert an element from the enumerable argument into an instance of
        /// the desired output element type. The position of the input element is also specified as an argument to this function. 
        /// 
        public Func ConvertElement { get { return this.map; } set { this.map = value; } } 
 
        /// 
        /// Gets or sets the function used to create the output collection from a list of converted enumerable elements. 
        /// 
        public Func, TResult> CreateResult { get { return this.collect; } set { this.collect = value; } }

        ///  
        /// Gets or sets an optional function that can retrieve the name of an element from the enumerable argument.
        /// If this function is set, duplicate input element names will result in an exception. Null or empty names will 
        /// not result in an exception. If specified, this function will be called after . 
        /// 
        public Func GetName { get { return this.deriveName; } set { this.deriveName = value; } } 

        /// 
        /// Validates the input enumerable, converting each input element and producing the final instance of  as a result.
        ///  
        /// The instance of  produced by calling the  function
        /// on the list of elements produced by calling the  function on each element of the input enumerable. 
        /// If the input enumerable itself is null 
        /// If  is a nullable type and any element of the input enumerable is null.
        /// If  is set and the actual number of input elements is not equal to this value. 
        /// If  is -1,  is set to false and the input enumerable is empty.
        /// If  is set and a duplicate name is derived for more than one input element.
        /// Other exceptions may be thrown by the  and  functions, and by the  function, if specified.
        internal TResult Validate() 
        {
            return EnumerableValidator.Validate(this.target, 
                                                                                  this.argumentName, 
                                                                                  this.ExpectedElementCount,
                                                                                  this.AllowEmpty, 
                                                                                  this.ConvertElement,
                                                                                  this.CreateResult,
                                                                                  this.GetName);
        } 

        private static TResult Validate(IEnumerable argument, 
                                        string argumentName, 
                                        int expectedElementCount,
                                        bool allowEmpty, 
                                        Func map,
                                        Func, TResult> collect,
                                        Func deriveName)
        { 
            Debug.Assert(map != null, "Set EnumerableValidator.ConvertElement before calling validate");
            Debug.Assert(collect != null, "Set EnumerableValidator.CreateResult before calling validate"); 
 
            EntityUtil.CheckArgumentNull(argument, argumentName);
 
            bool checkNull = (default(TElementIn) == null);
            bool checkCount = (expectedElementCount != -1);
            Dictionary nameIndex = null;
            if (deriveName != null) 
            {
                nameIndex = new Dictionary(); 
            } 

            int pos = 0; 
            List validatedElements = new List();
            foreach (TElementIn elementIn in argument)
            {
                // More elements in 'arguments' than expected? 
                if (checkCount && pos == expectedElementCount)
                { 
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_ExpressionList_IncorrectElementCount, argumentName); 
                }
 
                if (checkNull && elementIn == null)
                {
                    // Don't call FormatIndex unless an exception is actually being thrown
                    throw EntityUtil.ArgumentNull(StringUtil.FormatIndex(argumentName, pos)); 
                }
 
                TElementOut elementOut = map(elementIn, pos); 
                validatedElements.Add(elementOut);
 
                if (deriveName != null)
                {
                    string name = deriveName(elementIn, pos);
                    Debug.Assert(name != null, "GetName should not produce null"); 
                    int foundIndex = -1;
                    if (nameIndex.TryGetValue(name, out foundIndex)) 
                    { 
                        throw EntityUtil.Argument(
                            System.Data.Entity.Strings.Cqt_Util_CheckListDuplicateName(foundIndex, pos, name), 
                            StringUtil.FormatIndex(argumentName, pos)
                        );
                    }
                    nameIndex[name] = pos; 
                }
 
                pos++; 
            }
 
            // If an expected count was specified, the actual count must match
            if (checkCount)
            {
                if (pos != expectedElementCount) 
                {
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_ExpressionList_IncorrectElementCount, argumentName); 
                } 
            }
            else 
            {
                // No expected count was specified, simply verify empty vs. non-empty.
                if (0 == pos && !allowEmpty)
                { 
                    throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_Util_CheckListEmptyInvalid, argumentName);
                } 
            } 

            return collect(validatedElements); 
        }
    }
}

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