File: System\Linq\Parallel\Enumerables\EmptyEnumerable.cs
Project: ndp\fx\src\Core\System.Core.csproj (System.Core)
// ==++==
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// EmptyEnumerable.cs
//
// <OWNER>Microsoft</OWNER>
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
using System.Collections;
using System.Collections.Generic;
 
namespace System.Linq.Parallel
{
    /// <summary>
    /// We occ----ionally need a no-op enumerator to stand-in when we don't have data left
    /// within a partition's data stream. These are simple enumerable and enumerator
    /// implementations that always and consistently yield no elements.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal class EmptyEnumerable<T> : ParallelQuery<T>
    {
        private EmptyEnumerable()
            : base(QuerySettings.Empty)
        {
        }
 
        // A singleton cached and shared among callers.
        private static volatile EmptyEnumerable<T> s_instance;
        private static volatile EmptyEnumerator<T> s_enumeratorInstance;
 
        internal static EmptyEnumerable<T> Instance
        {
            get
            {
                if (s_instance == null)
                {
                    // There is no need for thread safety here.
                    s_instance = new EmptyEnumerable<T>();
                }
 
                return s_instance;
            }
        }
 
        public override IEnumerator<T> GetEnumerator()
        {
            if (s_enumeratorInstance == null)
            {
                // There is no need for thread safety here.
                s_enumeratorInstance = new EmptyEnumerator<T>();
            }
 
            return s_enumeratorInstance;
        }
    }
 
    internal class EmptyEnumerator<T> : QueryOperatorEnumerator<T, int>, IEnumerator<T>
    {
        internal override bool MoveNext(ref T currentElement, ref int currentKey)
        {
            return false;
        }
 
        // IEnumerator<T> methods.
        public T Current { get { return default(T); } }
        object IEnumerator.Current { get { return null; } }
        public bool MoveNext() { return false; }
        void Collections.IEnumerator.Reset() { }
    }
}