コード例 #1
0
        /// <summary>
        /// Actual code for SelectMany implementation. Instead of doing Cartesian Product, it
        /// performs zipping.
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TCollection"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="collectionSelector"></param>
        /// <param name="resultSelector"></param>
        /// <returns></returns>
        private static IEnumerable <TResult> SelectManyImpl <TSource, TCollection, TResult>(IZippable <TSource> source,
                                                                                            Func <TSource, int, IZippable <TCollection> > collectionSelector,
                                                                                            Func <TSource, TCollection, TResult> resultSelector)
        {
            int index = 0;

            using (var e1 = source.GetEnumerator())
            {
                // a default(TSource) causes that using nested "from" in LINQ won't work. Example of what's not allowed:
                // from entity in entities
                // from element in entity.collection <- this won't work
                // ....
                using (var e2 = collectionSelector(default(TSource), index++).GetEnumerator())
                {
                    while (true)
                    {
                        var isNext1 = e1.MoveNext();
                        var isNext2 = e2.MoveNext();
                        if (isNext1 && isNext2)
                        {
                            yield return(resultSelector(e1.Current, e2.Current));
                        }
                        else
                        {
                            yield break;
                        }
                    }
                }
            }
        }