SortExpressionBuilder.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 / DataSet / System / Data / SortExpressionBuilder.cs / 1305376 / SortExpressionBuilder.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Collections;
using System.Text;
using System.Data;
using System.Linq; 
using System.Diagnostics;
 
namespace System.Data 
{
 
    /// 
    /// This class represents a combined sort expression build using mutiple sort expressions.
    /// 
    ///  
    internal class SortExpressionBuilder : IComparer>
    { 
        /** 
         *  This class ensures multiple orderby/thenbys are handled correctly. Its semantics is as follows:
         * 
         * Query 1:
         * orderby a
         * thenby  b
         * orderby c 
         * orderby d
         * thenby  e 
         * 
         * is equivalent to:
         * 
         * Query 2:
         * orderby d
         * thenby  e
         * thenby  c 
         * thenby  a
         * thenby  b 
         * 
         **/
 
        //Selectors and comparers are mapped using the index in the list.
        //E.g: _comparers[i] is used with _selectors[i]

        LinkedList> _selectors = new LinkedList>(); 
        LinkedList> _comparers = new LinkedList>();
 
        LinkedListNode> _currentSelector = null; 
        LinkedListNode> _currentComparer = null;
 

        /// 
        /// Adds a sorting selector/comparer in the correct order
        ///  
        internal void Add(Func keySelector, Comparison compare, bool isOrderBy)
        { 
            Debug.Assert(keySelector != null); 
            Debug.Assert(compare != null);
            //Inputs are assumed to be valid. The burden for ensuring it is on the caller. 

            if (isOrderBy)
            {
                _currentSelector = _selectors.AddFirst(keySelector); 
                _currentComparer = _comparers.AddFirst(compare);
            } 
            else 
            {
                //ThenBy can only be called after OrderBy 
                Debug.Assert(_currentSelector != null);
                Debug.Assert(_currentComparer != null);

                _currentSelector = _selectors.AddAfter(_currentSelector, keySelector); 
                _currentComparer = _comparers.AddAfter(_currentComparer, compare);
            } 
        } 

 

        /// 
        /// Represents a Combined selector of all selectors added thusfar.
        ///  
        /// List of 'objects returned by each selector'. This list is the combined-selector
        public List Select(T row) 
        { 
            List result = new List();
 
            foreach (Func selector in _selectors)
            {
                result.Add(selector(row));
            } 

            return result; 
        } 

 

        /// 
        /// Represents a Comparer (of IComparer) that compares two combined-selectors using
        /// provided comparers for each individual selector. 
        /// Note: Comparison is done in the order it was Added.
        ///  
        /// Comparison result of the combined Sort comparer expression 
        public int Compare(List a, List b)
        { 
            Debug.Assert(a.Count == Count);

            int i = 0;
            foreach (Comparison compare in _comparers) 
            {
                int result = compare(a[i], b[i]); 
 
                if (result != 0)
                { 
                    return result;
                }
                i++;
            } 

            return 0; 
        } 

        internal int Count 
        {
            get
            {
                Debug.Assert(_selectors.Count == _comparers.Count); //weak now that we have two dimensions 
                return _selectors.Count;
            } 
        } 

        ///  
        /// Clones the SortexpressionBuilder and returns a new object
        /// that points to same comparer and selectors (in the same order).
        /// 
        ///  
        internal SortExpressionBuilder Clone()
        { 
            SortExpressionBuilder builder = new SortExpressionBuilder(); 

            foreach (Func selector in _selectors) 
            {
                if (selector == _currentSelector.Value)
                {
                    builder._currentSelector = builder._selectors.AddLast(selector); 
                }
                else 
                { 
                    builder._selectors.AddLast(selector);
                } 
            }


            foreach (Comparison comparer in _comparers) 
            {
                if (comparer == _currentComparer.Value) 
                { 
                    builder._currentComparer = builder._comparers.AddLast(comparer);
                } 
                else
                {
                    builder._comparers.AddLast(comparer);
                } 
            }
 
            return builder; 
        }
 
        /// 
        /// Clones the SortExpressinBuilder and casts to type TResult.
        /// 
        internal SortExpressionBuilder CloneCast() 
        {
            SortExpressionBuilder builder = new SortExpressionBuilder(); 
 
            foreach (Func selector in _selectors)
            { 
                if (selector == _currentSelector.Value)
                {
                    builder._currentSelector = builder._selectors.AddLast(r => selector((T)(object)r));
                } 
                else
                { 
                    builder._selectors.AddLast(r => selector((T)(object)r)); 
                }
            } 


            foreach (Comparison comparer in _comparers)
            { 
                if (comparer == _currentComparer.Value)
                { 
                    builder._currentComparer = builder._comparers.AddLast(comparer); 
                }
                else 
                {
                    builder._comparers.AddLast(comparer);
                }
            } 

            return builder; 
        } 

    } //end SortExpressionBuilder 
}

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