Some modifications to the OxyPlot library to back-port to .NET 2.0. Added the LINQBridge library for the LINQ based code in OxyPlot (the original .NET LINQ is not available in .NET 2.0).
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/HashSet.cs Sat Jun 08 17:06:00 2013 +0000
1.3 @@ -0,0 +1,27 @@
1.4 +
1.5 +namespace OxyPlot.WindowsForms {
1.6 + using System;
1.7 + using System.Collections.Generic;
1.8 + using System.Text;
1.9 +
1.10 + public class HashSet<T> {
1.11 +
1.12 + private readonly Dictionary<T, object> set = new Dictionary<T, object>();
1.13 +
1.14 + public bool Add(T value) {
1.15 + if (set.ContainsKey(value))
1.16 + return true;
1.17 +
1.18 + set.Add(value, null);
1.19 + return false;
1.20 + }
1.21 +
1.22 + public bool Contains(T value) {
1.23 + return set.ContainsKey(value);
1.24 + }
1.25 +
1.26 + public void Clear() {
1.27 + set.Clear();
1.28 + }
1.29 + }
1.30 +}
2.1 --- a/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj Sat Jun 08 16:53:22 2013 +0000
2.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj Sat Jun 08 17:06:00 2013 +0000
2.3 @@ -9,39 +9,41 @@
2.4 <AppDesignerFolder>Properties</AppDesignerFolder>
2.5 <RootNamespace>OxyPlot.WindowsForms</RootNamespace>
2.6 <AssemblyName>OxyPlot.WindowsForms</AssemblyName>
2.7 - <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
2.8 - <TargetFrameworkProfile>Client</TargetFrameworkProfile>
2.9 + <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
2.10 + <TargetFrameworkProfile>
2.11 + </TargetFrameworkProfile>
2.12 <FileAlignment>512</FileAlignment>
2.13 </PropertyGroup>
2.14 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
2.15 <DebugSymbols>true</DebugSymbols>
2.16 <DebugType>full</DebugType>
2.17 <Optimize>false</Optimize>
2.18 - <OutputPath>bin\Debug\NET40\</OutputPath>
2.19 + <OutputPath>Bin\Debug\</OutputPath>
2.20 <IntermediateOutputPath>obj\Debug\NET40\</IntermediateOutputPath>
2.21 - <DefineConstants>DEBUG;TRACE</DefineConstants>
2.22 + <DefineConstants>TRACE;DEBUG</DefineConstants>
2.23 <ErrorReport>prompt</ErrorReport>
2.24 <WarningLevel>4</WarningLevel>
2.25 </PropertyGroup>
2.26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
2.27 <DebugType>pdbonly</DebugType>
2.28 <Optimize>true</Optimize>
2.29 - <OutputPath>..\..\Output\NET40\</OutputPath>
2.30 + <OutputPath>Bin\Release\</OutputPath>
2.31 <IntermediateOutputPath>obj\Release\NET40\</IntermediateOutputPath>
2.32 <DefineConstants>TRACE</DefineConstants>
2.33 <ErrorReport>prompt</ErrorReport>
2.34 <WarningLevel>4</WarningLevel>
2.35 - <DocumentationFile>..\..\Output\NET40\OxyPlot.WindowsForms.XML</DocumentationFile>
2.36 + <DocumentationFile>
2.37 + </DocumentationFile>
2.38 </PropertyGroup>
2.39 <PropertyGroup>
2.40 <SignAssembly>true</SignAssembly>
2.41 </PropertyGroup>
2.42 <PropertyGroup>
2.43 - <AssemblyOriginatorKeyFile>OxyPlot.WindowsForms.snk</AssemblyOriginatorKeyFile>
2.44 + <AssemblyOriginatorKeyFile>
2.45 + </AssemblyOriginatorKeyFile>
2.46 </PropertyGroup>
2.47 <ItemGroup>
2.48 <Reference Include="System" />
2.49 - <Reference Include="System.Core" />
2.50 <Reference Include="System.Drawing" />
2.51 <Reference Include="System.Windows.Forms" />
2.52 </ItemGroup>
2.53 @@ -49,6 +51,7 @@
2.54 <Compile Include="..\GlobalAssemblyInfo.cs">
2.55 <Link>Properties\GlobalAssemblyInfo.cs</Link>
2.56 </Compile>
2.57 + <Compile Include="HashSet.cs" />
2.58 <Compile Include="Helpers\ConverterExtensions.cs" />
2.59 <Compile Include="GraphicsRenderContext.cs" />
2.60 <Compile Include="NamespaceDoc.cs" />
2.61 @@ -60,9 +63,6 @@
2.62 <Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
2.63 </ItemGroup>
2.64 <ItemGroup>
2.65 - <None Include="OxyPlot.WindowsForms.snk" />
2.66 - </ItemGroup>
2.67 - <ItemGroup>
2.68 <ProjectReference Include="..\OxyPlot\OxyPlot.csproj">
2.69 <Project>{7a0b35c0-dd17-4964-8e9a-44d6cecdc692}</Project>
2.70 <Name>OxyPlot</Name>
3.1 Binary file External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.snk has changed
4.1 --- a/External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs Sat Jun 08 16:53:22 2013 +0000
4.2 +++ b/External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs Sat Jun 08 17:06:00 2013 +0000
4.3 @@ -185,17 +185,6 @@
4.4 public DateTimeIntervalType MinorIntervalType { get; set; }
4.5
4.6 /// <summary>
4.7 - /// Gets or sets the time zone (used when formatting date/time values).
4.8 - /// </summary>
4.9 - /// <remarks>
4.10 - /// No date/time conversion will be performed if this property is null.
4.11 - /// </remarks>
4.12 - /// <value>
4.13 - /// The time zone info.
4.14 - /// </value>
4.15 - public TimeZoneInfo TimeZone { get; set; }
4.16 -
4.17 - /// <summary>
4.18 /// Creates a data point.
4.19 /// </summary>
4.20 /// <param name="x">
4.21 @@ -294,12 +283,6 @@
4.22 // convert the double value to a DateTime
4.23 var time = ToDateTime(x);
4.24
4.25 - // If a time zone is specified, convert the time
4.26 - if (this.TimeZone != null)
4.27 - {
4.28 - time = TimeZoneInfo.ConvertTime(time, this.TimeZone);
4.29 - }
4.30 -
4.31 string fmt = this.ActualStringFormat;
4.32 if (fmt == null)
4.33 {
4.34 @@ -348,11 +331,6 @@
4.35 {
4.36 var time = ToDateTime(x);
4.37
4.38 - if (this.TimeZone != null)
4.39 - {
4.40 - time = TimeZoneInfo.ConvertTime(time, this.TimeZone);
4.41 - }
4.42 -
4.43 return time;
4.44 }
4.45
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/External/OxyPlot/OxyPlot/LinqBridge.cs Sat Jun 08 17:06:00 2013 +0000
5.3 @@ -0,0 +1,3115 @@
5.4 +#region License, Terms and Author(s)
5.5 +//
5.6 +// LINQBridge
5.7 +// Copyright (c) 2007 Atif Aziz, Joseph Albahari. All rights reserved.
5.8 +//
5.9 +// Author(s):
5.10 +//
5.11 +// Atif Aziz, http://www.raboof.com
5.12 +//
5.13 +// This library is free software; you can redistribute it and/or modify it
5.14 +// under the terms of the New BSD License, a copy of which should have
5.15 +// been delivered along with this distribution.
5.16 +//
5.17 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5.18 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5.19 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
5.20 +// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
5.21 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5.22 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
5.23 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5.24 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5.25 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5.26 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
5.27 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5.28 +//
5.29 +#endregion
5.30 +
5.31 +#if LINQBRIDGE_LIB
5.32 +
5.33 +namespace System.Linq {
5.34 + public partial class Enumerable { }
5.35 + public partial interface IGrouping<out TKey, TElement> { }
5.36 + public partial interface ILookup<TKey, TElement> { }
5.37 + public partial interface IOrderedEnumerable<TElement> { }
5.38 +}
5.39 +
5.40 +namespace System.Runtime.CompilerServices {
5.41 + public partial class ExtensionAttribute { }
5.42 +}
5.43 +
5.44 +#endif
5.45 +
5.46 +// $Id: Enumerable.cs c08984d432b1 2012/04/17 16:05:19 azizatif $
5.47 +
5.48 +namespace System.Linq
5.49 +{
5.50 + #region Imports
5.51 +
5.52 + using System;
5.53 + using System.Collections;
5.54 + using System.Collections.Generic;
5.55 + using System.Diagnostics;
5.56 + using LinqBridge;
5.57 +
5.58 + #endregion
5.59 +
5.60 + /// <summary>
5.61 + /// Provides a set of static (Shared in Visual Basic) methods for
5.62 + /// querying objects that implement <see cref="IEnumerable{T}" />.
5.63 + /// </summary>
5.64 +
5.65 + static partial class Enumerable
5.66 + {
5.67 + /// <summary>
5.68 + /// Returns the input typed as <see cref="IEnumerable{T}"/>.
5.69 + /// </summary>
5.70 +
5.71 + public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
5.72 + {
5.73 + return source;
5.74 + }
5.75 +
5.76 + /// <summary>
5.77 + /// Returns an empty <see cref="IEnumerable{T}"/> that has the
5.78 + /// specified type argument.
5.79 + /// </summary>
5.80 +
5.81 + public static IEnumerable<TResult> Empty<TResult>()
5.82 + {
5.83 + return Sequence<TResult>.Empty;
5.84 + }
5.85 +
5.86 + /// <summary>
5.87 + /// Converts the elements of an <see cref="IEnumerable"/> to the
5.88 + /// specified type.
5.89 + /// </summary>
5.90 +
5.91 + public static IEnumerable<TResult> Cast<TResult>(
5.92 + this IEnumerable source)
5.93 + {
5.94 + if (source == null) throw new ArgumentNullException("source");
5.95 +
5.96 + return CastYield<TResult>(source);
5.97 + }
5.98 +
5.99 + private static IEnumerable<TResult> CastYield<TResult>(
5.100 + IEnumerable source)
5.101 + {
5.102 + foreach (var item in source)
5.103 + yield return (TResult) item;
5.104 + }
5.105 +
5.106 + /// <summary>
5.107 + /// Filters the elements of an <see cref="IEnumerable"/> based on a specified type.
5.108 + /// </summary>
5.109 +
5.110 + public static IEnumerable<TResult> OfType<TResult>(
5.111 + this IEnumerable source)
5.112 + {
5.113 + if (source == null) throw new ArgumentNullException("source");
5.114 +
5.115 + return OfTypeYield<TResult>(source);
5.116 + }
5.117 +
5.118 + private static IEnumerable<TResult> OfTypeYield<TResult>(
5.119 + IEnumerable source)
5.120 + {
5.121 + foreach (var item in source)
5.122 + if (item is TResult)
5.123 + yield return (TResult) item;
5.124 + }
5.125 +
5.126 + /// <summary>
5.127 + /// Generates a sequence of integral numbers within a specified range.
5.128 + /// </summary>
5.129 + /// <param name="start">The value of the first integer in the sequence.</param>
5.130 + /// <param name="count">The number of sequential integers to generate.</param>
5.131 +
5.132 + public static IEnumerable<int> Range(int start, int count)
5.133 + {
5.134 + if (count < 0)
5.135 + throw new ArgumentOutOfRangeException("count", count, null);
5.136 +
5.137 + var end = (long) start + count;
5.138 + if (end - 1 >= int.MaxValue)
5.139 + throw new ArgumentOutOfRangeException("count", count, null);
5.140 +
5.141 + return RangeYield(start, end);
5.142 + }
5.143 +
5.144 + private static IEnumerable<int> RangeYield(int start, long end)
5.145 + {
5.146 + for (var i = start; i < end; i++)
5.147 + yield return i;
5.148 + }
5.149 +
5.150 + /// <summary>
5.151 + /// Generates a sequence that contains one repeated value.
5.152 + /// </summary>
5.153 +
5.154 + public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count)
5.155 + {
5.156 + if (count < 0) throw new ArgumentOutOfRangeException("count", count, null);
5.157 +
5.158 + return RepeatYield(element, count);
5.159 + }
5.160 +
5.161 + private static IEnumerable<TResult> RepeatYield<TResult>(TResult element, int count)
5.162 + {
5.163 + for (var i = 0; i < count; i++)
5.164 + yield return element;
5.165 + }
5.166 +
5.167 + /// <summary>
5.168 + /// Filters a sequence of values based on a predicate.
5.169 + /// </summary>
5.170 +
5.171 + public static IEnumerable<TSource> Where<TSource>(
5.172 + this IEnumerable<TSource> source,
5.173 + Func<TSource, bool> predicate)
5.174 + {
5.175 + if (predicate == null) throw new ArgumentNullException("predicate");
5.176 +
5.177 + return source.Where((item, i) => predicate(item));
5.178 + }
5.179 +
5.180 + /// <summary>
5.181 + /// Filters a sequence of values based on a predicate.
5.182 + /// Each element's index is used in the logic of the predicate function.
5.183 + /// </summary>
5.184 +
5.185 + public static IEnumerable<TSource> Where<TSource>(
5.186 + this IEnumerable<TSource> source,
5.187 + Func<TSource, int, bool> predicate)
5.188 + {
5.189 + if (source == null) throw new ArgumentNullException("source");
5.190 + if (predicate == null) throw new ArgumentNullException("predicate");
5.191 +
5.192 + return WhereYield(source, predicate);
5.193 + }
5.194 +
5.195 + private static IEnumerable<TSource> WhereYield<TSource>(
5.196 + IEnumerable<TSource> source,
5.197 + Func<TSource, int, bool> predicate)
5.198 + {
5.199 + var i = 0;
5.200 + foreach (var item in source)
5.201 + if (predicate(item, i++))
5.202 + yield return item;
5.203 + }
5.204 +
5.205 + /// <summary>
5.206 + /// Projects each element of a sequence into a new form.
5.207 + /// </summary>
5.208 +
5.209 + public static IEnumerable<TResult> Select<TSource, TResult>(
5.210 + this IEnumerable<TSource> source,
5.211 + Func<TSource, TResult> selector)
5.212 + {
5.213 + if (selector == null) throw new ArgumentNullException("selector");
5.214 +
5.215 + return source.Select((item, i) => selector(item));
5.216 + }
5.217 +
5.218 + /// <summary>
5.219 + /// Projects each element of a sequence into a new form by
5.220 + /// incorporating the element's index.
5.221 + /// </summary>
5.222 +
5.223 + public static IEnumerable<TResult> Select<TSource, TResult>(
5.224 + this IEnumerable<TSource> source,
5.225 + Func<TSource, int, TResult> selector)
5.226 + {
5.227 + if (source == null) throw new ArgumentNullException("source");
5.228 + if (selector == null) throw new ArgumentNullException("selector");
5.229 +
5.230 + return SelectYield(source, selector);
5.231 + }
5.232 +
5.233 + private static IEnumerable<TResult> SelectYield<TSource, TResult>(
5.234 + IEnumerable<TSource> source,
5.235 + Func<TSource, int, TResult> selector)
5.236 + {
5.237 + var i = 0;
5.238 + foreach (var item in source)
5.239 + yield return selector(item, i++);
5.240 + }
5.241 +
5.242 + /// <summary>
5.243 + /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />
5.244 + /// and flattens the resulting sequences into one sequence.
5.245 + /// </summary>
5.246 +
5.247 + public static IEnumerable<TResult> SelectMany<TSource, TResult>(
5.248 + this IEnumerable<TSource> source,
5.249 + Func<TSource, IEnumerable<TResult>> selector)
5.250 + {
5.251 + if (selector == null) throw new ArgumentNullException("selector");
5.252 +
5.253 + return source.SelectMany((item, i) => selector(item));
5.254 + }
5.255 +
5.256 + /// <summary>
5.257 + /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
5.258 + /// and flattens the resulting sequences into one sequence. The
5.259 + /// index of each source element is used in the projected form of
5.260 + /// that element.
5.261 + /// </summary>
5.262 +
5.263 + public static IEnumerable<TResult> SelectMany<TSource, TResult>(
5.264 + this IEnumerable<TSource> source,
5.265 + Func<TSource, int, IEnumerable<TResult>> selector)
5.266 + {
5.267 + if (selector == null) throw new ArgumentNullException("selector");
5.268 +
5.269 + return source.SelectMany(selector, (item, subitem) => subitem);
5.270 + }
5.271 +
5.272 + /// <summary>
5.273 + /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
5.274 + /// flattens the resulting sequences into one sequence, and invokes
5.275 + /// a result selector function on each element therein.
5.276 + /// </summary>
5.277 +
5.278 + public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
5.279 + this IEnumerable<TSource> source,
5.280 + Func<TSource, IEnumerable<TCollection>> collectionSelector,
5.281 + Func<TSource, TCollection, TResult> resultSelector)
5.282 + {
5.283 + if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
5.284 +
5.285 + return source.SelectMany((item, i) => collectionSelector(item), resultSelector);
5.286 + }
5.287 +
5.288 + /// <summary>
5.289 + /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
5.290 + /// flattens the resulting sequences into one sequence, and invokes
5.291 + /// a result selector function on each element therein. The index of
5.292 + /// each source element is used in the intermediate projected form
5.293 + /// of that element.
5.294 + /// </summary>
5.295 +
5.296 + public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
5.297 + this IEnumerable<TSource> source,
5.298 + Func<TSource, int, IEnumerable<TCollection>> collectionSelector,
5.299 + Func<TSource, TCollection, TResult> resultSelector)
5.300 + {
5.301 + if (source == null) throw new ArgumentNullException("source");
5.302 + if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
5.303 + if (resultSelector == null) throw new ArgumentNullException("resultSelector");
5.304 +
5.305 + return SelectManyYield(source, collectionSelector, resultSelector);
5.306 + }
5.307 +
5.308 + private static IEnumerable<TResult> SelectManyYield<TSource, TCollection, TResult>(
5.309 + this IEnumerable<TSource> source,
5.310 + Func<TSource, int, IEnumerable<TCollection>> collectionSelector,
5.311 + Func<TSource, TCollection, TResult> resultSelector)
5.312 + {
5.313 + var i = 0;
5.314 + foreach (var item in source)
5.315 + foreach (var subitem in collectionSelector(item, i++))
5.316 + yield return resultSelector(item, subitem);
5.317 + }
5.318 +
5.319 + /// <summary>
5.320 + /// Returns elements from a sequence as long as a specified condition is true.
5.321 + /// </summary>
5.322 +
5.323 + public static IEnumerable<TSource> TakeWhile<TSource>(
5.324 + this IEnumerable<TSource> source,
5.325 + Func<TSource, bool> predicate)
5.326 + {
5.327 + if (predicate == null) throw new ArgumentNullException("predicate");
5.328 +
5.329 + return source.TakeWhile((item, i) => predicate(item));
5.330 + }
5.331 +
5.332 + /// <summary>
5.333 + /// Returns elements from a sequence as long as a specified condition is true.
5.334 + /// The element's index is used in the logic of the predicate function.
5.335 + /// </summary>
5.336 +
5.337 + public static IEnumerable<TSource> TakeWhile<TSource>(
5.338 + this IEnumerable<TSource> source,
5.339 + Func<TSource, int, bool> predicate)
5.340 + {
5.341 + if (source == null) throw new ArgumentNullException("source");
5.342 + if (predicate == null) throw new ArgumentNullException("predicate");
5.343 +
5.344 + return TakeWhileYield(source, predicate);
5.345 + }
5.346 +
5.347 + private static IEnumerable<TSource> TakeWhileYield<TSource>(
5.348 + this IEnumerable<TSource> source,
5.349 + Func<TSource, int, bool> predicate)
5.350 + {
5.351 + var i = 0;
5.352 + foreach (var item in source)
5.353 + if (predicate(item, i++))
5.354 + yield return item;
5.355 + else
5.356 + break;
5.357 + }
5.358 +
5.359 + /// <summary>
5.360 + /// Returns a specified number of contiguous elements from the start
5.361 + /// of a sequence.
5.362 + /// </summary>
5.363 +
5.364 + public static IEnumerable<TSource> Take<TSource>(
5.365 + this IEnumerable<TSource> source,
5.366 + int count)
5.367 + {
5.368 + return source.TakeWhile((item, i) => i < count);
5.369 + }
5.370 +
5.371 + private static class Futures<T>
5.372 + {
5.373 + public static readonly Func<T> Default = () => default(T);
5.374 + public static readonly Func<T> Undefined = () => { throw new InvalidOperationException(); };
5.375 + }
5.376 +
5.377 + /// <summary>
5.378 + /// Base implementation of First operator.
5.379 + /// </summary>
5.380 +
5.381 + private static TSource FirstImpl<TSource>(
5.382 + this IEnumerable<TSource> source,
5.383 + Func<TSource> empty)
5.384 + {
5.385 + if (source == null) throw new ArgumentNullException("source");
5.386 + Debug.Assert(empty != null);
5.387 +
5.388 + var list = source as IList<TSource>; // optimized case for lists
5.389 + if (list != null)
5.390 + return list.Count > 0 ? list[0] : empty();
5.391 +
5.392 + using (var e = source.GetEnumerator()) // fallback for enumeration
5.393 + return e.MoveNext() ? e.Current : empty();
5.394 + }
5.395 +
5.396 + /// <summary>
5.397 + /// Returns the first element of a sequence.
5.398 + /// </summary>
5.399 +
5.400 + public static TSource First<TSource>(
5.401 + this IEnumerable<TSource> source)
5.402 + {
5.403 + return source.FirstImpl(Futures<TSource>.Undefined);
5.404 + }
5.405 +
5.406 + /// <summary>
5.407 + /// Returns the first element in a sequence that satisfies a specified condition.
5.408 + /// </summary>
5.409 +
5.410 + public static TSource First<TSource>(
5.411 + this IEnumerable<TSource> source,
5.412 + Func<TSource, bool> predicate)
5.413 + {
5.414 + return First(source.Where(predicate));
5.415 + }
5.416 +
5.417 + /// <summary>
5.418 + /// Returns the first element of a sequence, or a default value if
5.419 + /// the sequence contains no elements.
5.420 + /// </summary>
5.421 +
5.422 + public static TSource FirstOrDefault<TSource>(
5.423 + this IEnumerable<TSource> source)
5.424 + {
5.425 + return source.FirstImpl(Futures<TSource>.Default);
5.426 + }
5.427 +
5.428 + /// <summary>
5.429 + /// Returns the first element of the sequence that satisfies a
5.430 + /// condition or a default value if no such element is found.
5.431 + /// </summary>
5.432 +
5.433 + public static TSource FirstOrDefault<TSource>(
5.434 + this IEnumerable<TSource> source,
5.435 + Func<TSource, bool> predicate)
5.436 + {
5.437 + return FirstOrDefault(source.Where(predicate));
5.438 + }
5.439 +
5.440 + /// <summary>
5.441 + /// Base implementation of Last operator.
5.442 + /// </summary>
5.443 +
5.444 + private static TSource LastImpl<TSource>(
5.445 + this IEnumerable<TSource> source,
5.446 + Func<TSource> empty)
5.447 + {
5.448 + if (source == null) throw new ArgumentNullException("source");
5.449 +
5.450 + var list = source as IList<TSource>; // optimized case for lists
5.451 + if (list != null)
5.452 + return list.Count > 0 ? list[list.Count - 1] : empty();
5.453 +
5.454 + using (var e = source.GetEnumerator())
5.455 + {
5.456 + if (!e.MoveNext())
5.457 + return empty();
5.458 +
5.459 + var last = e.Current;
5.460 + while (e.MoveNext())
5.461 + last = e.Current;
5.462 +
5.463 + return last;
5.464 + }
5.465 + }
5.466 +
5.467 + /// <summary>
5.468 + /// Returns the last element of a sequence.
5.469 + /// </summary>
5.470 + public static TSource Last<TSource>(
5.471 + this IEnumerable<TSource> source)
5.472 + {
5.473 + return source.LastImpl(Futures<TSource>.Undefined);
5.474 + }
5.475 +
5.476 + /// <summary>
5.477 + /// Returns the last element of a sequence that satisfies a
5.478 + /// specified condition.
5.479 + /// </summary>
5.480 +
5.481 + public static TSource Last<TSource>(
5.482 + this IEnumerable<TSource> source,
5.483 + Func<TSource, bool> predicate)
5.484 + {
5.485 + return Last(source.Where(predicate));
5.486 + }
5.487 +
5.488 + /// <summary>
5.489 + /// Returns the last element of a sequence, or a default value if
5.490 + /// the sequence contains no elements.
5.491 + /// </summary>
5.492 +
5.493 + public static TSource LastOrDefault<TSource>(
5.494 + this IEnumerable<TSource> source)
5.495 + {
5.496 + return source.LastImpl(Futures<TSource>.Default);
5.497 + }
5.498 +
5.499 + /// <summary>
5.500 + /// Returns the last element of a sequence that satisfies a
5.501 + /// condition or a default value if no such element is found.
5.502 + /// </summary>
5.503 +
5.504 + public static TSource LastOrDefault<TSource>(
5.505 + this IEnumerable<TSource> source,
5.506 + Func<TSource, bool> predicate)
5.507 + {
5.508 + return LastOrDefault(source.Where(predicate));
5.509 + }
5.510 +
5.511 + /// <summary>
5.512 + /// Base implementation of Single operator.
5.513 + /// </summary>
5.514 +
5.515 + private static TSource SingleImpl<TSource>(
5.516 + this IEnumerable<TSource> source,
5.517 + Func<TSource> empty)
5.518 + {
5.519 + if (source == null) throw new ArgumentNullException("source");
5.520 +
5.521 + using (var e = source.GetEnumerator())
5.522 + {
5.523 + if (e.MoveNext())
5.524 + {
5.525 + var single = e.Current;
5.526 + if (!e.MoveNext())
5.527 + return single;
5.528 +
5.529 + throw new InvalidOperationException();
5.530 + }
5.531 +
5.532 + return empty();
5.533 + }
5.534 + }
5.535 +
5.536 + /// <summary>
5.537 + /// Returns the only element of a sequence, and throws an exception
5.538 + /// if there is not exactly one element in the sequence.
5.539 + /// </summary>
5.540 +
5.541 + public static TSource Single<TSource>(
5.542 + this IEnumerable<TSource> source)
5.543 + {
5.544 + return source.SingleImpl(Futures<TSource>.Undefined);
5.545 + }
5.546 +
5.547 + /// <summary>
5.548 + /// Returns the only element of a sequence that satisfies a
5.549 + /// specified condition, and throws an exception if more than one
5.550 + /// such element exists.
5.551 + /// </summary>
5.552 +
5.553 + public static TSource Single<TSource>(
5.554 + this IEnumerable<TSource> source,
5.555 + Func<TSource, bool> predicate)
5.556 + {
5.557 + return Single(source.Where(predicate));
5.558 + }
5.559 +
5.560 + /// <summary>
5.561 + /// Returns the only element of a sequence, or a default value if
5.562 + /// the sequence is empty; this method throws an exception if there
5.563 + /// is more than one element in the sequence.
5.564 + /// </summary>
5.565 +
5.566 + public static TSource SingleOrDefault<TSource>(
5.567 + this IEnumerable<TSource> source)
5.568 + {
5.569 + return source.SingleImpl(Futures<TSource>.Default);
5.570 + }
5.571 +
5.572 + /// <summary>
5.573 + /// Returns the only element of a sequence that satisfies a
5.574 + /// specified condition or a default value if no such element
5.575 + /// exists; this method throws an exception if more than one element
5.576 + /// satisfies the condition.
5.577 + /// </summary>
5.578 +
5.579 + public static TSource SingleOrDefault<TSource>(
5.580 + this IEnumerable<TSource> source,
5.581 + Func<TSource, bool> predicate)
5.582 + {
5.583 + return SingleOrDefault(source.Where(predicate));
5.584 + }
5.585 +
5.586 + /// <summary>
5.587 + /// Returns the element at a specified index in a sequence.
5.588 + /// </summary>
5.589 +
5.590 + public static TSource ElementAt<TSource>(
5.591 + this IEnumerable<TSource> source,
5.592 + int index)
5.593 + {
5.594 + if (source == null) throw new ArgumentNullException("source");
5.595 +
5.596 + if (index < 0)
5.597 + throw new ArgumentOutOfRangeException("index", index, null);
5.598 +
5.599 + var list = source as IList<TSource>;
5.600 + if (list != null)
5.601 + return list[index];
5.602 +
5.603 + try
5.604 + {
5.605 + return source.SkipWhile((item, i) => i < index).First();
5.606 + }
5.607 + catch (InvalidOperationException) // if thrown by First
5.608 + {
5.609 + throw new ArgumentOutOfRangeException("index", index, null);
5.610 + }
5.611 + }
5.612 +
5.613 + /// <summary>
5.614 + /// Returns the element at a specified index in a sequence or a
5.615 + /// default value if the index is out of range.
5.616 + /// </summary>
5.617 +
5.618 + public static TSource ElementAtOrDefault<TSource>(
5.619 + this IEnumerable<TSource> source,
5.620 + int index)
5.621 + {
5.622 + if (source == null) throw new ArgumentNullException("source");
5.623 +
5.624 + if (index < 0)
5.625 + return default(TSource);
5.626 +
5.627 + var list = source as IList<TSource>;
5.628 + if (list != null)
5.629 + return index < list.Count ? list[index] : default(TSource);
5.630 +
5.631 + return source.SkipWhile((item, i) => i < index).FirstOrDefault();
5.632 + }
5.633 +
5.634 + /// <summary>
5.635 + /// Inverts the order of the elements in a sequence.
5.636 + /// </summary>
5.637 +
5.638 + public static IEnumerable<TSource> Reverse<TSource>(
5.639 + this IEnumerable<TSource> source)
5.640 + {
5.641 + if (source == null) throw new ArgumentNullException("source");
5.642 +
5.643 + return ReverseYield(source);
5.644 + }
5.645 +
5.646 + private static IEnumerable<TSource> ReverseYield<TSource>(IEnumerable<TSource> source)
5.647 + {
5.648 + var stack = new Stack<TSource>();
5.649 + foreach (var item in source)
5.650 + stack.Push(item);
5.651 +
5.652 + foreach (var item in stack)
5.653 + yield return item;
5.654 + }
5.655 +
5.656 + /// <summary>
5.657 + /// Bypasses elements in a sequence as long as a specified condition
5.658 + /// is true and then returns the remaining elements.
5.659 + /// </summary>
5.660 +
5.661 + public static IEnumerable<TSource> SkipWhile<TSource>(
5.662 + this IEnumerable<TSource> source,
5.663 + Func<TSource, bool> predicate)
5.664 + {
5.665 + if (predicate == null) throw new ArgumentNullException("predicate");
5.666 +
5.667 + return source.SkipWhile((item, i) => predicate(item));
5.668 + }
5.669 +
5.670 + /// <summary>
5.671 + /// Bypasses elements in a sequence as long as a specified condition
5.672 + /// is true and then returns the remaining elements. The element's
5.673 + /// index is used in the logic of the predicate function.
5.674 + /// </summary>
5.675 +
5.676 + public static IEnumerable<TSource> SkipWhile<TSource>(
5.677 + this IEnumerable<TSource> source,
5.678 + Func<TSource, int, bool> predicate)
5.679 + {
5.680 + if (source == null) throw new ArgumentNullException("source");
5.681 + if (predicate == null) throw new ArgumentNullException("predicate");
5.682 +
5.683 + return SkipWhileYield(source, predicate);
5.684 + }
5.685 +
5.686 + private static IEnumerable<TSource> SkipWhileYield<TSource>(
5.687 + IEnumerable<TSource> source,
5.688 + Func<TSource, int, bool> predicate)
5.689 + {
5.690 + using (var e = source.GetEnumerator())
5.691 + {
5.692 + for (var i = 0; ; i++)
5.693 + {
5.694 + if (!e.MoveNext())
5.695 + yield break;
5.696 +
5.697 + if (!predicate(e.Current, i))
5.698 + break;
5.699 + }
5.700 +
5.701 + do { yield return e.Current; } while (e.MoveNext());
5.702 + }
5.703 + }
5.704 +
5.705 + /// <summary>
5.706 + /// Bypasses a specified number of elements in a sequence and then
5.707 + /// returns the remaining elements.
5.708 + /// </summary>
5.709 +
5.710 + public static IEnumerable<TSource> Skip<TSource>(
5.711 + this IEnumerable<TSource> source,
5.712 + int count)
5.713 + {
5.714 + return source.SkipWhile((item, i) => i < count);
5.715 + }
5.716 +
5.717 + /// <summary>
5.718 + /// Returns the number of elements in a sequence.
5.719 + /// </summary>
5.720 +
5.721 + public static int Count<TSource>(
5.722 + this IEnumerable<TSource> source)
5.723 + {
5.724 + if (source == null) throw new ArgumentNullException("source");
5.725 +
5.726 + var collection = source as ICollection;
5.727 + return collection != null
5.728 + ? collection.Count
5.729 + : source.Aggregate(0, (count, item) => checked(count + 1));
5.730 + }
5.731 +
5.732 + /// <summary>
5.733 + /// Returns a number that represents how many elements in the
5.734 + /// specified sequence satisfy a condition.
5.735 + /// </summary>
5.736 +
5.737 + public static int Count<TSource>(
5.738 + this IEnumerable<TSource> source,
5.739 + Func<TSource, bool> predicate)
5.740 + {
5.741 + return Count(source.Where(predicate));
5.742 + }
5.743 +
5.744 + /// <summary>
5.745 + /// Returns an <see cref="Int64"/> that represents the total number
5.746 + /// of elements in a sequence.
5.747 + /// </summary>
5.748 +
5.749 + public static long LongCount<TSource>(
5.750 + this IEnumerable<TSource> source)
5.751 + {
5.752 + if (source == null) throw new ArgumentNullException("source");
5.753 +
5.754 + var array = source as Array;
5.755 + return array != null
5.756 + ? array.LongLength
5.757 + : source.Aggregate(0L, (count, item) => count + 1);
5.758 + }
5.759 +
5.760 + /// <summary>
5.761 + /// Returns an <see cref="Int64"/> that represents how many elements
5.762 + /// in a sequence satisfy a condition.
5.763 + /// </summary>
5.764 +
5.765 + public static long LongCount<TSource>(
5.766 + this IEnumerable<TSource> source,
5.767 + Func<TSource, bool> predicate)
5.768 + {
5.769 + return LongCount(source.Where(predicate));
5.770 + }
5.771 +
5.772 + /// <summary>
5.773 + /// Concatenates two sequences.
5.774 + /// </summary>
5.775 +
5.776 + public static IEnumerable<TSource> Concat<TSource>(
5.777 + this IEnumerable<TSource> first,
5.778 + IEnumerable<TSource> second)
5.779 + {
5.780 + if (first == null) throw new ArgumentNullException("first");
5.781 + if (second == null) throw new ArgumentNullException("second");
5.782 +
5.783 + return ConcatYield(first, second);
5.784 + }
5.785 +
5.786 + private static IEnumerable<TSource> ConcatYield<TSource>(
5.787 + IEnumerable<TSource> first,
5.788 + IEnumerable<TSource> second)
5.789 + {
5.790 + foreach (var item in first)
5.791 + yield return item;
5.792 +
5.793 + foreach (var item in second)
5.794 + yield return item;
5.795 + }
5.796 +
5.797 + /// <summary>
5.798 + /// Creates a <see cref="List{T}"/> from an <see cref="IEnumerable{T}"/>.
5.799 + /// </summary>
5.800 +
5.801 + public static List<TSource> ToList<TSource>(
5.802 + this IEnumerable<TSource> source)
5.803 + {
5.804 + if (source == null) throw new ArgumentNullException("source");
5.805 +
5.806 + return new List<TSource>(source);
5.807 + }
5.808 +
5.809 + /// <summary>
5.810 + /// Creates an array from an <see cref="IEnumerable{T}"/>.
5.811 + /// </summary>
5.812 +
5.813 + public static TSource[] ToArray<TSource>(
5.814 + this IEnumerable<TSource> source)
5.815 + {
5.816 + return source.ToList().ToArray();
5.817 + }
5.818 +
5.819 + /// <summary>
5.820 + /// Returns distinct elements from a sequence by using the default
5.821 + /// equality comparer to compare values.
5.822 + /// </summary>
5.823 +
5.824 + public static IEnumerable<TSource> Distinct<TSource>(
5.825 + this IEnumerable<TSource> source)
5.826 + {
5.827 + return Distinct(source, /* comparer */ null);
5.828 + }
5.829 +
5.830 + /// <summary>
5.831 + /// Returns distinct elements from a sequence by using a specified
5.832 + /// <see cref="IEqualityComparer{T}"/> to compare values.
5.833 + /// </summary>
5.834 +
5.835 + public static IEnumerable<TSource> Distinct<TSource>(
5.836 + this IEnumerable<TSource> source,
5.837 + IEqualityComparer<TSource> comparer)
5.838 + {
5.839 + if (source == null) throw new ArgumentNullException("source");
5.840 +
5.841 + return DistinctYield(source, comparer);
5.842 + }
5.843 +
5.844 + private static IEnumerable<TSource> DistinctYield<TSource>(
5.845 + IEnumerable<TSource> source,
5.846 + IEqualityComparer<TSource> comparer)
5.847 + {
5.848 + var set = new Dictionary<TSource, object>(comparer);
5.849 + var gotNull = false;
5.850 +
5.851 + foreach (var item in source)
5.852 + {
5.853 + if (item == null)
5.854 + {
5.855 + if (gotNull)
5.856 + continue;
5.857 + gotNull = true;
5.858 + }
5.859 + else
5.860 + {
5.861 + if (set.ContainsKey(item))
5.862 + continue;
5.863 + set.Add(item, null);
5.864 + }
5.865 +
5.866 + yield return item;
5.867 + }
5.868 + }
5.869 +
5.870 + /// <summary>
5.871 + /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
5.872 + /// <see cref="IEnumerable{T}" /> according to a specified key
5.873 + /// selector function.
5.874 + /// </summary>
5.875 +
5.876 + public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
5.877 + this IEnumerable<TSource> source,
5.878 + Func<TSource, TKey> keySelector)
5.879 + {
5.880 + return ToLookup(source, keySelector, e => e, /* comparer */ null);
5.881 + }
5.882 +
5.883 + /// <summary>
5.884 + /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
5.885 + /// <see cref="IEnumerable{T}" /> according to a specified key
5.886 + /// selector function and a key comparer.
5.887 + /// </summary>
5.888 +
5.889 + public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
5.890 + this IEnumerable<TSource> source,
5.891 + Func<TSource, TKey> keySelector,
5.892 + IEqualityComparer<TKey> comparer)
5.893 + {
5.894 + return ToLookup(source, keySelector, e => e, comparer);
5.895 + }
5.896 +
5.897 + /// <summary>
5.898 + /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
5.899 + /// <see cref="IEnumerable{T}" /> according to specified key
5.900 + /// and element selector functions.
5.901 + /// </summary>
5.902 +
5.903 + public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
5.904 + this IEnumerable<TSource> source,
5.905 + Func<TSource, TKey> keySelector,
5.906 + Func<TSource, TElement> elementSelector)
5.907 + {
5.908 + return ToLookup(source, keySelector, elementSelector, /* comparer */ null);
5.909 + }
5.910 +
5.911 + /// <summary>
5.912 + /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
5.913 + /// <see cref="IEnumerable{T}" /> according to a specified key
5.914 + /// selector function, a comparer and an element selector function.
5.915 + /// </summary>
5.916 +
5.917 + public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
5.918 + this IEnumerable<TSource> source,
5.919 + Func<TSource, TKey> keySelector,
5.920 + Func<TSource, TElement> elementSelector,
5.921 + IEqualityComparer<TKey> comparer)
5.922 + {
5.923 + if (source == null) throw new ArgumentNullException("source");
5.924 + if (keySelector == null) throw new ArgumentNullException("keySelector");
5.925 + if (elementSelector == null) throw new ArgumentNullException("elementSelector");
5.926 +
5.927 + var lookup = new Lookup<TKey, TElement>(comparer);
5.928 +
5.929 + foreach (var item in source)
5.930 + {
5.931 + var key = keySelector(item);
5.932 +
5.933 + var grouping = (Grouping<TKey, TElement>) lookup.Find(key);
5.934 + if (grouping == null)
5.935 + {
5.936 + grouping = new Grouping<TKey, TElement>(key);
5.937 + lookup.Add(grouping);
5.938 + }
5.939 +
5.940 + grouping.Add(elementSelector(item));
5.941 + }
5.942 +
5.943 + return lookup;
5.944 + }
5.945 +
5.946 + /// <summary>
5.947 + /// Groups the elements of a sequence according to a specified key
5.948 + /// selector function.
5.949 + /// </summary>
5.950 +
5.951 + public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
5.952 + this IEnumerable<TSource> source,
5.953 + Func<TSource, TKey> keySelector)
5.954 + {
5.955 + return GroupBy(source, keySelector, /* comparer */ null);
5.956 + }
5.957 +
5.958 + /// <summary>
5.959 + /// Groups the elements of a sequence according to a specified key
5.960 + /// selector function and compares the keys by using a specified
5.961 + /// comparer.
5.962 + /// </summary>
5.963 +
5.964 + public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
5.965 + this IEnumerable<TSource> source,
5.966 + Func<TSource, TKey> keySelector,
5.967 + IEqualityComparer<TKey> comparer)
5.968 + {
5.969 + return GroupBy(source, keySelector, e => e, comparer);
5.970 + }
5.971 +
5.972 + /// <summary>
5.973 + /// Groups the elements of a sequence according to a specified key
5.974 + /// selector function and projects the elements for each group by
5.975 + /// using a specified function.
5.976 + /// </summary>
5.977 +
5.978 + public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
5.979 + this IEnumerable<TSource> source,
5.980 + Func<TSource, TKey> keySelector,
5.981 + Func<TSource, TElement> elementSelector)
5.982 + {
5.983 + return GroupBy(source, keySelector, elementSelector, /* comparer */ null);
5.984 + }
5.985 +
5.986 + /// <summary>
5.987 + /// Groups the elements of a sequence according to a specified key
5.988 + /// selector function and creates a result value from each group and
5.989 + /// its key.
5.990 + /// </summary>
5.991 +
5.992 + public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
5.993 + this IEnumerable<TSource> source,
5.994 + Func<TSource, TKey> keySelector,
5.995 + Func<TSource, TElement> elementSelector,
5.996 + IEqualityComparer<TKey> comparer)
5.997 + {
5.998 + if (source == null) throw new ArgumentNullException("source");
5.999 + if (keySelector == null) throw new ArgumentNullException("keySelector");
5.1000 + if (elementSelector == null) throw new ArgumentNullException("elementSelector");
5.1001 +
5.1002 + return ToLookup(source, keySelector, elementSelector, comparer);
5.1003 + }
5.1004 +
5.1005 + /// <summary>
5.1006 + /// Groups the elements of a sequence according to a key selector
5.1007 + /// function. The keys are compared by using a comparer and each
5.1008 + /// group's elements are projected by using a specified function.
5.1009 + /// </summary>
5.1010 +
5.1011 + public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
5.1012 + this IEnumerable<TSource> source,
5.1013 + Func<TSource, TKey> keySelector,
5.1014 + Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
5.1015 + {
5.1016 + return GroupBy(source, keySelector, resultSelector, /* comparer */ null);
5.1017 + }
5.1018 +
5.1019 + /// <summary>
5.1020 + /// Groups the elements of a sequence according to a specified key
5.1021 + /// selector function and creates a result value from each group and
5.1022 + /// its key. The elements of each group are projected by using a
5.1023 + /// specified function.
5.1024 + /// </summary>
5.1025 +
5.1026 + public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
5.1027 + this IEnumerable<TSource> source,
5.1028 + Func<TSource, TKey> keySelector,
5.1029 + Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
5.1030 + IEqualityComparer<TKey> comparer)
5.1031 + {
5.1032 + if (source == null) throw new ArgumentNullException("source");
5.1033 + if (keySelector == null) throw new ArgumentNullException("keySelector");
5.1034 + if (resultSelector == null) throw new ArgumentNullException("resultSelector");
5.1035 +
5.1036 + return ToLookup(source, keySelector, comparer).Select(g => resultSelector(g.Key, g));
5.1037 + }
5.1038 +
5.1039 + /// <summary>
5.1040 + /// Groups the elements of a sequence according to a specified key
5.1041 + /// selector function and creates a result value from each group and
5.1042 + /// its key. The keys are compared by using a specified comparer.
5.1043 + /// </summary>
5.1044 +
5.1045 + public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
5.1046 + this IEnumerable<TSource> source,
5.1047 + Func<TSource, TKey> keySelector,
5.1048 + Func<TSource, TElement> elementSelector,
5.1049 + Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
5.1050 + {
5.1051 + return GroupBy(source, keySelector, elementSelector, resultSelector, /* comparer */ null);
5.1052 + }
5.1053 +
5.1054 + /// <summary>
5.1055 + /// Groups the elements of a sequence according to a specified key
5.1056 + /// selector function and creates a result value from each group and
5.1057 + /// its key. Key values are compared by using a specified comparer,
5.1058 + /// and the elements of each group are projected by using a
5.1059 + /// specified function.
5.1060 + /// </summary>
5.1061 +
5.1062 + public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
5.1063 + this IEnumerable<TSource> source,
5.1064 + Func<TSource, TKey> keySelector,
5.1065 + Func<TSource, TElement> elementSelector,
5.1066 + Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
5.1067 + IEqualityComparer<TKey> comparer)
5.1068 + {
5.1069 + if (source == null) throw new ArgumentNullException("source");
5.1070 + if (keySelector == null) throw new ArgumentNullException("keySelector");
5.1071 + if (elementSelector == null) throw new ArgumentNullException("elementSelector");
5.1072 + if (resultSelector == null) throw new ArgumentNullException("resultSelector");
5.1073 +
5.1074 + return ToLookup(source, keySelector, elementSelector, comparer)
5.1075 + .Select(g => resultSelector(g.Key, g));
5.1076 + }
5.1077 +
5.1078 + /// <summary>
5.1079 + /// Applies an accumulator function over a sequence.
5.1080 + /// </summary>
5.1081 +
5.1082 + public static TSource Aggregate<TSource>(
5.1083 + this IEnumerable<TSource> source,
5.1084 + Func<TSource, TSource, TSource> func)
5.1085 + {
5.1086 + if (source == null) throw new ArgumentNullException("source");
5.1087 + if (func == null) throw new ArgumentNullException("func");
5.1088 +
5.1089 + using (var e = source.GetEnumerator())
5.1090 + {
5.1091 + if (!e.MoveNext())
5.1092 + throw new InvalidOperationException();
5.1093 +
5.1094 + return e.Renumerable().Skip(1).Aggregate(e.Current, func);
5.1095 + }
5.1096 + }
5.1097 +
5.1098 + /// <summary>
5.1099 + /// Applies an accumulator function over a sequence. The specified
5.1100 + /// seed value is used as the initial accumulator value.
5.1101 + /// </summary>
5.1102 +
5.1103 + public static TAccumulate Aggregate<TSource, TAccumulate>(
5.1104 + this IEnumerable<TSource> source,
5.1105 + TAccumulate seed,
5.1106 + Func<TAccumulate, TSource, TAccumulate> func)
5.1107 + {
5.1108 + return Aggregate(source, seed, func, r => r);
5.1109 + }
5.1110 +
5.1111 + /// <summary>
5.1112 + /// Applies an accumulator function over a sequence. The specified
5.1113 + /// seed value is used as the initial accumulator value, and the
5.1114 + /// specified function is used to select the result value.
5.1115 + /// </summary>
5.1116 +
5.1117 + public static TResult Aggregate<TSource, TAccumulate, TResult>(
5.1118 + this IEnumerable<TSource> source,
5.1119 + TAccumulate seed,
5.1120 + Func<TAccumulate, TSource, TAccumulate> func,
5.1121 + Func<TAccumulate, TResult> resultSelector)
5.1122 + {
5.1123 + if (source == null) throw new ArgumentNullException("source");
5.1124 + if (func == null) throw new ArgumentNullException("func");
5.1125 + if (resultSelector == null) throw new ArgumentNullException("resultSelector");
5.1126 +
5.1127 + var result = seed;
5.1128 +
5.1129 + foreach (var item in source)
5.1130 + result = func(result, item);
5.1131 +
5.1132 + return resultSelector(result);
5.1133 + }
5.1134 +
5.1135 + /// <summary>
5.1136 + /// Produces the set union of two sequences by using the default
5.1137 + /// equality comparer.
5.1138 + /// </summary>
5.1139 +
5.1140 + public static IEnumerable<TSource> Union<TSource>(
5.1141 + this IEnumerable<TSource> first,
5.1142 + IEnumerable<TSource> second)
5.1143 + {
5.1144 + return Union(first, second, /* comparer */ null);
5.1145 + }
5.1146 +
5.1147 + /// <summary>
5.1148 + /// Produces the set union of two sequences by using a specified
5.1149 + /// <see cref="IEqualityComparer{T}" />.
5.1150 + /// </summary>
5.1151 +
5.1152 + public static IEnumerable<TSource> Union<TSource>(
5.1153 + this IEnumerable<TSource> first,
5.1154 + IEnumerable<TSource> second,
5.1155 + IEqualityComparer<TSource> comparer)
5.1156 + {
5.1157 + return first.Concat(second).Distinct(comparer);
5.1158 + }
5.1159 +
5.1160 + /// <summary>
5.1161 + /// Returns the elements of the specified sequence or the type
5.1162 + /// parameter's default value in a singleton collection if the
5.1163 + /// sequence is empty.
5.1164 + /// </summary>
5.1165 +
5.1166 + public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
5.1167 + this IEnumerable<TSource> source)
5.1168 + {
5.1169 + return source.DefaultIfEmpty(default(TSource));
5.1170 + }
5.1171 +
5.1172 + /// <summary>
5.1173 + /// Returns the elements of the specified sequence or the specified
5.1174 + /// value in a singleton collection if the sequence is empty.
5.1175 + /// </summary>
5.1176 +
5.1177 + public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
5.1178 + this IEnumerable<TSource> source,
5.1179 + TSource defaultValue)
5.1180 + {
5.1181 + if (source == null) throw new ArgumentNullException("source");
5.1182 +
5.1183 + return DefaultIfEmptyYield(source, defaultValue);
5.1184 + }
5.1185 +
5.1186 + private static IEnumerable<TSource> DefaultIfEmptyYield<TSource>(
5.1187 + IEnumerable<TSource> source,
5.1188 + TSource defaultValue)
5.1189 + {
5.1190 + using (var e = source.GetEnumerator())
5.1191 + {
5.1192 + if (!e.MoveNext())
5.1193 + yield return defaultValue;
5.1194 + else
5.1195 + do { yield return e.Current; } while (e.MoveNext());
5.1196 + }
5.1197 + }
5.1198 +
5.1199 + /// <summary>
5.1200 + /// Determines whether all elements of a sequence satisfy a condition.
5.1201 + /// </summary>
5.1202 +
5.1203 + public static bool All<TSource>(
5.1204 + this IEnumerable<TSource> source,
5.1205 + Func<TSource, bool> predicate)
5.1206 + {
5.1207 + if (source == null) throw new ArgumentNullException("source");
5.1208 + if (predicate == null) throw new ArgumentNullException("predicate");
5.1209 +
5.1210 + foreach (var item in source)
5.1211 + if (!predicate(item))
5.1212 + return false;
5.1213 +
5.1214 + return true;
5.1215 + }
5.1216 +
5.1217 + /// <summary>
5.1218 + /// Determines whether a sequence contains any elements.
5.1219 + /// </summary>
5.1220 +
5.1221 + public static bool Any<TSource>(
5.1222 + this IEnumerable<TSource> source)
5.1223 + {
5.1224 + if (source == null) throw new ArgumentNullException("source");
5.1225 +
5.1226 + using (var e = source.GetEnumerator())
5.1227 + return e.MoveNext();
5.1228 + }
5.1229 +
5.1230 + /// <summary>
5.1231 + /// Determines whether any element of a sequence satisfies a
5.1232 + /// condition.
5.1233 + /// </summary>
5.1234 +
5.1235 + public static bool Any<TSource>(
5.1236 + this IEnumerable<TSource> source,
5.1237 + Func<TSource, bool> predicate)
5.1238 + {
5.1239 + return source.Where(predicate).Any();
5.1240 + }
5.1241 +
5.1242 + /// <summary>
5.1243 + /// Determines whether a sequence contains a specified element by
5.1244 + /// using the default equality comparer.
5.1245 + /// </summary>
5.1246 +
5.1247 + public static bool Contains<TSource>(
5.1248 + this IEnumerable<TSource> source,
5.1249 + TSource value)
5.1250 + {
5.1251 + return source.Contains(value, /* comparer */ null);
5.1252 + }
5.1253 +
5.1254 + /// <summary>
5.1255 + /// Determines whether a sequence contains a specified element by
5.1256 + /// using a specified <see cref="IEqualityComparer{T}" />.
5.1257 + /// </summary>
5.1258 +
5.1259 + public static bool Contains<TSource>(
5.1260 + this IEnumerable<TSource> source,
5.1261 + TSource value,
5.1262 + IEqualityComparer<TSource> comparer)
5.1263 + {
5.1264 + if (source == null) throw new ArgumentNullException("source");
5.1265 +
5.1266 + if (comparer == null)
5.1267 + {
5.1268 + var collection = source as ICollection<TSource>;
5.1269 + if (collection != null)
5.1270 + return collection.Contains(value);
5.1271 + }
5.1272 +
5.1273 + comparer = comparer ?? EqualityComparer<TSource>.Default;
5.1274 + return source.Any(item => comparer.Equals(item, value));
5.1275 + }
5.1276 +
5.1277 + /// <summary>
5.1278 + /// Determines whether two sequences are equal by comparing the
5.1279 + /// elements by using the default equality comparer for their type.
5.1280 + /// </summary>
5.1281 +
5.1282 + public static bool SequenceEqual<TSource>(
5.1283 + this IEnumerable<TSource> first,
5.1284 + IEnumerable<TSource> second)
5.1285 + {
5.1286 + return first.SequenceEqual(second, /* comparer */ null);
5.1287 + }
5.1288 +
5.1289 + /// <summary>
5.1290 + /// Determines whether two sequences are equal by comparing their
5.1291 + /// elements by using a specified <see cref="IEqualityComparer{T}" />.
5.1292 + /// </summary>
5.1293 +
5.1294 + public static bool SequenceEqual<TSource>(
5.1295 + this IEnumerable<TSource> first,
5.1296 + IEnumerable<TSource> second,
5.1297 + IEqualityComparer<TSource> comparer)
5.1298 + {
5.1299 + if (first == null) throw new ArgumentNullException("frist");
5.1300 + if (second == null) throw new ArgumentNullException("second");
5.1301 +
5.1302 + comparer = comparer ?? EqualityComparer<TSource>.Default;
5.1303 +
5.1304 + using (IEnumerator<TSource> lhs = first.GetEnumerator(),
5.1305 + rhs = second.GetEnumerator())
5.1306 + {
5.1307 + do
5.1308 + {
5.1309 + if (!lhs.MoveNext())
5.1310 + return !rhs.MoveNext();
5.1311 +
5.1312 + if (!rhs.MoveNext())
5.1313 + return false;
5.1314 + }
5.1315 + while (comparer.Equals(lhs.Current, rhs.Current));
5.1316 + }
5.1317 +
5.1318 + return false;
5.1319 + }
5.1320 +
5.1321 + /// <summary>
5.1322 + /// Base implementation for Min/Max operator.
5.1323 + /// </summary>
5.1324 +
5.1325 + private static TSource MinMaxImpl<TSource>(
5.1326 + this IEnumerable<TSource> source,
5.1327 + Func<TSource, TSource, bool> lesser)
5.1328 + {
5.1329 + if (source == null) throw new ArgumentNullException("source");
5.1330 + Debug.Assert(lesser != null);
5.1331 +
5.1332 + if (typeof(TSource).IsClass) // ReSharper disable CompareNonConstrainedGenericWithNull
5.1333 + source = source.Where(e => e != null).DefaultIfEmpty(); // ReSharper restore CompareNonConstrainedGenericWithNull
5.1334 +
5.1335 + return source.Aggregate((a, item) => lesser(a, item) ? a : item);
5.1336 + }
5.1337 +
5.1338 + /// <summary>
5.1339 + /// Base implementation for Min/Max operator for nullable types.
5.1340 + /// </summary>
5.1341 +
5.1342 + private static TSource? MinMaxImpl<TSource>(
5.1343 + this IEnumerable<TSource?> source,
5.1344 + TSource? seed, Func<TSource?, TSource?, bool> lesser) where TSource : struct
5.1345 + {
5.1346 + if (source == null) throw new ArgumentNullException("source");
5.1347 + Debug.Assert(lesser != null);
5.1348 +
5.1349 + return source.Aggregate(seed, (a, item) => lesser(a, item) ? a : item);
5.1350 + // == MinMaxImpl(Repeat<TSource?>(null, 1).Concat(source), lesser);
5.1351 + }
5.1352 +
5.1353 + /// <summary>
5.1354 + /// Returns the minimum value in a generic sequence.
5.1355 + /// </summary>
5.1356 +
5.1357 + public static TSource Min<TSource>(
5.1358 + this IEnumerable<TSource> source)
5.1359 + {
5.1360 + var comparer = Comparer<TSource>.Default;
5.1361 + return source.MinMaxImpl((x, y) => comparer.Compare(x, y) < 0);
5.1362 + }
5.1363 +
5.1364 + /// <summary>
5.1365 + /// Invokes a transform function on each element of a generic
5.1366 + /// sequence and returns the minimum resulting value.
5.1367 + /// </summary>
5.1368 +
5.1369 + public static TResult Min<TSource, TResult>(
5.1370 + this IEnumerable<TSource> source,
5.1371 + Func<TSource, TResult> selector)
5.1372 + {
5.1373 + return source.Select(selector).Min();
5.1374 + }
5.1375 +
5.1376 + /// <summary>
5.1377 + /// Returns the maximum value in a generic sequence.
5.1378 + /// </summary>
5.1379 +
5.1380 + public static TSource Max<TSource>(
5.1381 + this IEnumerable<TSource> source)
5.1382 + {
5.1383 + var comparer = Comparer<TSource>.Default;
5.1384 + return source.MinMaxImpl((x, y) => comparer.Compare(x, y) > 0);
5.1385 + }
5.1386 +
5.1387 + /// <summary>
5.1388 + /// Invokes a transform function on each element of a generic
5.1389 + /// sequence and returns the maximum resulting value.
5.1390 + /// </summary>
5.1391 +
5.1392 + public static TResult Max<TSource, TResult>(
5.1393 + this IEnumerable<TSource> source,
5.1394 + Func<TSource, TResult> selector)
5.1395 + {
5.1396 + return source.Select(selector).Max();
5.1397 + }
5.1398 +
5.1399 + /// <summary>
5.1400 + /// Makes an enumerator seen as enumerable once more.
5.1401 + /// </summary>
5.1402 + /// <remarks>
5.1403 + /// The supplied enumerator must have been started. The first element
5.1404 + /// returned is the element the enumerator was on when passed in.
5.1405 + /// DO NOT use this method if the caller must be a generator. It is
5.1406 + /// mostly safe among aggregate operations.
5.1407 + /// </remarks>
5.1408 +
5.1409 + private static IEnumerable<T> Renumerable<T>(this IEnumerator<T> e)
5.1410 + {
5.1411 + Debug.Assert(e != null);
5.1412 +
5.1413 + do { yield return e.Current; } while (e.MoveNext());
5.1414 + }
5.1415 +
5.1416 + /// <summary>
5.1417 + /// Sorts the elements of a sequence in ascending order according to a key.
5.1418 + /// </summary>
5.1419 +
5.1420 + public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
5.1421 + this IEnumerable<TSource> source,
5.1422 + Func<TSource, TKey> keySelector)
5.1423 + {
5.1424 + return source.OrderBy(keySelector, /* comparer */ null);
5.1425 + }
5.1426 +
5.1427 + /// <summary>
5.1428 + /// Sorts the elements of a sequence in ascending order by using a
5.1429 + /// specified comparer.
5.1430 + /// </summary>
5.1431 +
5.1432 + public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
5.1433 + this IEnumerable<TSource> source,
5.1434 + Func<TSource, TKey> keySelector,
5.1435 + IComparer<TKey> comparer)
5.1436 + {
5.1437 + if (source == null) throw new ArgumentNullException("source");
5.1438 + if (keySelector == null) throw new ArgumentNullException("keySelector");
5.1439 +
5.1440 + return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ false);
5.1441 + }
5.1442 +
5.1443 + /// <summary>
5.1444 + /// Sorts the elements of a sequence in descending order according to a key.
5.1445 + /// </summary>
5.1446 +
5.1447 + public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
5.1448 + this IEnumerable<TSource> source,
5.1449 + Func<TSource, TKey> keySelector)
5.1450 + {
5.1451 + return source.OrderByDescending(keySelector, /* comparer */ null);
5.1452 + }
5.1453 +
5.1454 + /// <summary>
5.1455 + /// Sorts the elements of a sequence in descending order by using a
5.1456 + /// specified comparer.
5.1457 + /// </summary>
5.1458 +
5.1459 + public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
5.1460 + this IEnumerable<TSource> source,
5.1461 + Func<TSource, TKey> keySelector,
5.1462 + IComparer<TKey> comparer)
5.1463 + {
5.1464 + if (source == null) throw new ArgumentNullException("source");
5.1465 + if (source == null) throw new ArgumentNullException("keySelector");
5.1466 +
5.1467 + return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ true);
5.1468 + }
5.1469 +
5.1470 + /// <summary>
5.1471 + /// Performs a subsequent ordering of the elements in a sequence in
5.1472 + /// ascending order according to a key.
5.1473 + /// </summary>
5.1474 +
5.1475 + public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
5.1476 + this IOrderedEnumerable<TSource> source,
5.1477 + Func<TSource, TKey> keySelector)
5.1478 + {
5.1479 + return source.ThenBy(keySelector, /* comparer */ null);
5.1480 + }
5.1481 +
5.1482 + /// <summary>
5.1483 + /// Performs a subsequent ordering of the elements in a sequence in
5.1484 + /// ascending order by using a specified comparer.
5.1485 + /// </summary>
5.1486 +
5.1487 + public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
5.1488 + this IOrderedEnumerable<TSource> source,
5.1489 + Func<TSource, TKey> keySelector,
5.1490 + IComparer<TKey> comparer)
5.1491 + {
5.1492 + if (source == null) throw new ArgumentNullException("source");
5.1493 +
5.1494 + return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ false);
5.1495 + }
5.1496 +
5.1497 + /// <summary>
5.1498 + /// Performs a subsequent ordering of the elements in a sequence in
5.1499 + /// descending order, according to a key.
5.1500 + /// </summary>
5.1501 +
5.1502 + public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
5.1503 + this IOrderedEnumerable<TSource> source,
5.1504 + Func<TSource, TKey> keySelector)
5.1505 + {
5.1506 + return source.ThenByDescending(keySelector, /* comparer */ null);
5.1507 + }
5.1508 +
5.1509 + /// <summary>
5.1510 + /// Performs a subsequent ordering of the elements in a sequence in
5.1511 + /// descending order by using a specified comparer.
5.1512 + /// </summary>
5.1513 +
5.1514 + public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
5.1515 + this IOrderedEnumerable<TSource> source,
5.1516 + Func<TSource, TKey> keySelector,
5.1517 + IComparer<TKey> comparer)
5.1518 + {
5.1519 + if (source == null) throw new ArgumentNullException("source");
5.1520 +
5.1521 + return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ true);
5.1522 + }
5.1523 +
5.1524 + /// <summary>
5.1525 + /// Base implementation for Intersect and Except operators.
5.1526 + /// </summary>
5.1527 +
5.1528 + private static IEnumerable<TSource> IntersectExceptImpl<TSource>(
5.1529 + this IEnumerable<TSource> first,
5.1530 + IEnumerable<TSource> second,
5.1531 + IEqualityComparer<TSource> comparer,
5.1532 + bool flag)
5.1533 + {
5.1534 + if (first == null) throw new ArgumentNullException("first");
5.1535 + if (second == null) throw new ArgumentNullException("second");
5.1536 +
5.1537 + var keys = new List<Key<TSource>>();
5.1538 + var flags = new Dictionary<Key<TSource>, bool>(new KeyComparer<TSource>(comparer));
5.1539 +
5.1540 + foreach (var item in from item in first
5.1541 + select new Key<TSource>(item) into item
5.1542 + where !flags.ContainsKey(item)
5.1543 + select item)
5.1544 + {
5.1545 + flags.Add(item, !flag);
5.1546 + keys.Add(item);
5.1547 + }
5.1548 +
5.1549 + foreach (var item in from item in second
5.1550 + select new Key<TSource>(item) into item
5.1551 + where flags.ContainsKey(item)
5.1552 + select item)
5.1553 + {
5.1554 + flags[item] = flag;
5.1555 + }
5.1556 +
5.1557 + //
5.1558 + // As per docs, "the marked elements are yielded in the order in
5.1559 + // which they were collected.
5.1560 + //
5.1561 +
5.1562 + return from item in keys where flags[item] select item.Value;
5.1563 + }
5.1564 +
5.1565 + /// <summary>
5.1566 + /// Produces the set intersection of two sequences by using the
5.1567 + /// default equality comparer to compare values.
5.1568 + /// </summary>
5.1569 +
5.1570 + public static IEnumerable<TSource> Intersect<TSource>(
5.1571 + this IEnumerable<TSource> first,
5.1572 + IEnumerable<TSource> second)
5.1573 + {
5.1574 + return first.Intersect(second, /* comparer */ null);
5.1575 + }
5.1576 +
5.1577 + /// <summary>
5.1578 + /// Produces the set intersection of two sequences by using the
5.1579 + /// specified <see cref="IEqualityComparer{T}" /> to compare values.
5.1580 + /// </summary>
5.1581 +
5.1582 + public static IEnumerable<TSource> Intersect<TSource>(
5.1583 + this IEnumerable<TSource> first,
5.1584 + IEnumerable<TSource> second,
5.1585 + IEqualityComparer<TSource> comparer)
5.1586 + {
5.1587 + return IntersectExceptImpl(first, second, comparer, /* flag */ true);
5.1588 + }
5.1589 +
5.1590 + /// <summary>
5.1591 + /// Produces the set difference of two sequences by using the
5.1592 + /// default equality comparer to compare values.
5.1593 + /// </summary>
5.1594 +
5.1595 + public static IEnumerable<TSource> Except<TSource>(
5.1596 + this IEnumerable<TSource> first,
5.1597 + IEnumerable<TSource> second)
5.1598 + {
5.1599 + return first.Except(second, /* comparer */ null);
5.1600 + }
5.1601 +
5.1602 + /// <summary>
5.1603 + /// Produces the set difference of two sequences by using the
5.1604 + /// specified <see cref="IEqualityComparer{T}" /> to compare values.
5.1605 + /// </summary>
5.1606 +
5.1607 + public static IEnumerable<TSource> Except<TSource>(
5.1608 + this IEnumerable<TSource> first,
5.1609 + IEnumerable<TSource> second,
5.1610 + IEqualityComparer<TSource> comparer)
5.1611 + {
5.1612 + return IntersectExceptImpl(first, second, comparer, /* flag */ false);
5.1613 + }
5.1614 +
5.1615 + /// <summary>
5.1616 + /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
5.1617 + /// <see cref="IEnumerable{T}" /> according to a specified key
5.1618 + /// selector function.
5.1619 + /// </summary>
5.1620 +
5.1621 + public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
5.1622 + this IEnumerable<TSource> source,
5.1623 + Func<TSource, TKey> keySelector)
5.1624 + {
5.1625 + return source.ToDictionary(keySelector, /* comparer */ null);
5.1626 + }
5.1627 +
5.1628 + /// <summary>
5.1629 + /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
5.1630 + /// <see cref="IEnumerable{T}" /> according to a specified key
5.1631 + /// selector function and key comparer.
5.1632 + /// </summary>
5.1633 +
5.1634 + public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
5.1635 + this IEnumerable<TSource> source,
5.1636 + Func<TSource, TKey> keySelector,
5.1637 + IEqualityComparer<TKey> comparer)
5.1638 + {
5.1639 + return source.ToDictionary(keySelector, e => e, comparer);
5.1640 + }
5.1641 +
5.1642 + /// <summary>
5.1643 + /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
5.1644 + /// <see cref="IEnumerable{T}" /> according to specified key
5.1645 + /// selector and element selector functions.
5.1646 + /// </summary>
5.1647 +
5.1648 + public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
5.1649 + this IEnumerable<TSource> source,
5.1650 + Func<TSource, TKey> keySelector,
5.1651 + Func<TSource, TElement> elementSelector)
5.1652 + {
5.1653 + return source.ToDictionary(keySelector, elementSelector, /* comparer */ null);
5.1654 + }
5.1655 +
5.1656 + /// <summary>
5.1657 + /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
5.1658 + /// <see cref="IEnumerable{T}" /> according to a specified key
5.1659 + /// selector function, a comparer, and an element selector function.
5.1660 + /// </summary>
5.1661 +
5.1662 + public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
5.1663 + this IEnumerable<TSource> source,
5.1664 + Func<TSource, TKey> keySelector,
5.1665 + Func<TSource, TElement> elementSelector,
5.1666 + IEqualityComparer<TKey> comparer)
5.1667 + {
5.1668 + if (source == null) throw new ArgumentNullException("source");
5.1669 + if (keySelector == null) throw new ArgumentNullException("keySelector");
5.1670 + if (elementSelector == null) throw new ArgumentNullException("elementSelector");
5.1671 +
5.1672 + var dict = new Dictionary<TKey, TElement>(comparer);
5.1673 +
5.1674 + foreach (var item in source)
5.1675 + {
5.1676 + //
5.1677 + // ToDictionary is meant to throw ArgumentNullException if
5.1678 + // keySelector produces a key that is null and
5.1679 + // Argument exception if keySelector produces duplicate keys
5.1680 + // for two elements. Incidentally, the doucmentation for
5.1681 + // IDictionary<TKey, TValue>.Add says that the Add method
5.1682 + // throws the same exceptions under the same circumstances
5.1683 + // so we don't need to do any additional checking or work
5.1684 + // here and let the Add implementation do all the heavy
5.1685 + // lifting.
5.1686 + //
5.1687 +
5.1688 + dict.Add(keySelector(item), elementSelector(item));
5.1689 + }
5.1690 +
5.1691 + return dict;
5.1692 + }
5.1693 +
5.1694 + /// <summary>
5.1695 + /// Correlates the elements of two sequences based on matching keys.
5.1696 + /// The default equality comparer is used to compare keys.
5.1697 + /// </summary>
5.1698 +
5.1699 + public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
5.1700 + this IEnumerable<TOuter> outer,
5.1701 + IEnumerable<TInner> inner,
5.1702 + Func<TOuter, TKey> outerKeySelector,
5.1703 + Func<TInner, TKey> innerKeySelector,
5.1704 + Func<TOuter, TInner, TResult> resultSelector)
5.1705 + {
5.1706 + return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
5.1707 + }
5.1708 +
5.1709 + /// <summary>
5.1710 + /// Correlates the elements of two sequences based on matching keys.
5.1711 + /// The default equality comparer is used to compare keys. A
5.1712 + /// specified <see cref="IEqualityComparer{T}" /> is used to compare keys.
5.1713 + /// </summary>
5.1714 +
5.1715 + public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
5.1716 + this IEnumerable<TOuter> outer,
5.1717 + IEnumerable<TInner> inner,
5.1718 + Func<TOuter, TKey> outerKeySelector,
5.1719 + Func<TInner, TKey> innerKeySelector,
5.1720 + Func<TOuter, TInner, TResult> resultSelector,
5.1721 + IEqualityComparer<TKey> comparer)
5.1722 + {
5.1723 + if (outer == null) throw new ArgumentNullException("outer");
5.1724 + if (inner == null) throw new ArgumentNullException("inner");
5.1725 + if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
5.1726 + if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
5.1727 + if (resultSelector == null) throw new ArgumentNullException("resultSelector");
5.1728 +
5.1729 + var lookup = inner.ToLookup(innerKeySelector, comparer);
5.1730 +
5.1731 + return
5.1732 + from o in outer
5.1733 + from i in lookup[outerKeySelector(o)]
5.1734 + select resultSelector(o, i);
5.1735 + }
5.1736 +
5.1737 + /// <summary>
5.1738 + /// Correlates the elements of two sequences based on equality of
5.1739 + /// keys and groups the results. The default equality comparer is
5.1740 + /// used to compare keys.
5.1741 + /// </summary>
5.1742 +
5.1743 + public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
5.1744 + this IEnumerable<TOuter> outer,
5.1745 + IEnumerable<TInner> inner,
5.1746 + Func<TOuter, TKey> outerKeySelector,
5.1747 + Func<TInner, TKey> innerKeySelector,
5.1748 + Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
5.1749 + {
5.1750 + return outer.GroupJoin(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
5.1751 + }
5.1752 +
5.1753 + /// <summary>
5.1754 + /// Correlates the elements of two sequences based on equality of
5.1755 + /// keys and groups the results. The default equality comparer is
5.1756 + /// used to compare keys. A specified <see cref="IEqualityComparer{T}" />
5.1757 + /// is used to compare keys.
5.1758 + /// </summary>
5.1759 +
5.1760 + public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
5.1761 + this IEnumerable<TOuter> outer,
5.1762 + IEnumerable<TInner> inner,
5.1763 + Func<TOuter, TKey> outerKeySelector,
5.1764 + Func<TInner, TKey> innerKeySelector,
5.1765 + Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
5.1766 + IEqualityComparer<TKey> comparer)
5.1767 + {
5.1768 + if (outer == null) throw new ArgumentNullException("outer");
5.1769 + if (inner == null) throw new ArgumentNullException("inner");
5.1770 + if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
5.1771 + if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
5.1772 + if (resultSelector == null) throw new ArgumentNullException("resultSelector");
5.1773 +
5.1774 + var lookup = inner.ToLookup(innerKeySelector, comparer);
5.1775 + return outer.Select(o => resultSelector(o, lookup[outerKeySelector(o)]));
5.1776 + }
5.1777 +
5.1778 + private static class Sequence<T>
5.1779 + {
5.1780 + public static readonly IEnumerable<T> Empty = new T[0];
5.1781 + }
5.1782 +
5.1783 + private sealed class Grouping<K, V> : List<V>, IGrouping<K, V>
5.1784 + {
5.1785 + internal Grouping(K key)
5.1786 + {
5.1787 + Key = key;
5.1788 + }
5.1789 +
5.1790 + public K Key { get; private set; }
5.1791 + }
5.1792 + }
5.1793 +}
5.1794 +
5.1795 +// $Id: Enumerable.g.tt 71137f497bf2 2012/04/16 20:01:27 azizatif $
5.1796 +
5.1797 +namespace System.Linq
5.1798 +{
5.1799 + #region Imports
5.1800 +
5.1801 + using System;
5.1802 + using System.Collections.Generic;
5.1803 +
5.1804 + #endregion
5.1805 +
5.1806 + // This partial implementation was template-generated:
5.1807 + // Mon, 16 Apr 2012 20:05:53 GMT
5.1808 +
5.1809 + partial class Enumerable
5.1810 + {
5.1811 + /// <summary>
5.1812 + /// Computes the sum of a sequence of nullable <see cref="System.Int32" /> values.
5.1813 + /// </summary>
5.1814 +
5.1815 + public static int Sum(
5.1816 + this IEnumerable<int> source)
5.1817 + {
5.1818 + if (source == null) throw new ArgumentNullException("source");
5.1819 +
5.1820 + int sum = 0;
5.1821 + foreach (var num in source)
5.1822 + sum = checked(sum + num);
5.1823 +
5.1824 + return sum;
5.1825 + }
5.1826 +
5.1827 + /// <summary>
5.1828 + /// Computes the sum of a sequence of nullable <see cref="System.Int32" />
5.1829 + /// values that are obtained by invoking a transform function on
5.1830 + /// each element of the input sequence.
5.1831 + /// </summary>
5.1832 +
5.1833 + public static int Sum<TSource>(
5.1834 + this IEnumerable<TSource> source,
5.1835 + Func<TSource, int> selector)
5.1836 + {
5.1837 + return source.Select(selector).Sum();
5.1838 + }
5.1839 +
5.1840 + /// <summary>
5.1841 + /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values.
5.1842 + /// </summary>
5.1843 +
5.1844 + public static double Average(
5.1845 + this IEnumerable<int> source)
5.1846 + {
5.1847 + if (source == null) throw new ArgumentNullException("source");
5.1848 +
5.1849 + long sum = 0;
5.1850 + long count = 0;
5.1851 +
5.1852 + foreach (var num in source)
5.1853 + checked
5.1854 + {
5.1855 + sum += (int) num;
5.1856 + count++;
5.1857 + }
5.1858 +
5.1859 + if (count == 0)
5.1860 + throw new InvalidOperationException();
5.1861 +
5.1862 + return (double) sum / count;
5.1863 + }
5.1864 +
5.1865 + /// <summary>
5.1866 + /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values
5.1867 + /// that are obtained by invoking a transform function on each
5.1868 + /// element of the input sequence.
5.1869 + /// </summary>
5.1870 +
5.1871 + public static double Average<TSource>(
5.1872 + this IEnumerable<TSource> source,
5.1873 + Func<TSource, int> selector)
5.1874 + {
5.1875 + return source.Select(selector).Average();
5.1876 + }
5.1877 +
5.1878 +
5.1879 + /// <summary>
5.1880 + /// Computes the sum of a sequence of <see cref="System.Int32" /> values.
5.1881 + /// </summary>
5.1882 +
5.1883 + public static int? Sum(
5.1884 + this IEnumerable<int?> source)
5.1885 + {
5.1886 + if (source == null) throw new ArgumentNullException("source");
5.1887 +
5.1888 + int sum = 0;
5.1889 + foreach (var num in source)
5.1890 + sum = checked(sum + (num ?? 0));
5.1891 +
5.1892 + return sum;
5.1893 + }
5.1894 +
5.1895 + /// <summary>
5.1896 + /// Computes the sum of a sequence of <see cref="System.Int32" />
5.1897 + /// values that are obtained by invoking a transform function on
5.1898 + /// each element of the input sequence.
5.1899 + /// </summary>
5.1900 +
5.1901 + public static int? Sum<TSource>(
5.1902 + this IEnumerable<TSource> source,
5.1903 + Func<TSource, int?> selector)
5.1904 + {
5.1905 + return source.Select(selector).Sum();
5.1906 + }
5.1907 +
5.1908 + /// <summary>
5.1909 + /// Computes the average of a sequence of <see cref="System.Int32" /> values.
5.1910 + /// </summary>
5.1911 +
5.1912 + public static double? Average(
5.1913 + this IEnumerable<int?> source)
5.1914 + {
5.1915 + if (source == null) throw new ArgumentNullException("source");
5.1916 +
5.1917 + long sum = 0;
5.1918 + long count = 0;
5.1919 +
5.1920 + foreach (var num in source.Where(n => n != null))
5.1921 + checked
5.1922 + {
5.1923 + sum += (int) num;
5.1924 + count++;
5.1925 + }
5.1926 +
5.1927 + if (count == 0)
5.1928 + return null;
5.1929 +
5.1930 + return (double?) sum / count;
5.1931 + }
5.1932 +
5.1933 + /// <summary>
5.1934 + /// Computes the average of a sequence of <see cref="System.Int32" /> values
5.1935 + /// that are obtained by invoking a transform function on each
5.1936 + /// element of the input sequence.
5.1937 + /// </summary>
5.1938 +
5.1939 + public static double? Average<TSource>(
5.1940 + this IEnumerable<TSource> source,
5.1941 + Func<TSource, int?> selector)
5.1942 + {
5.1943 + return source.Select(selector).Average();
5.1944 + }
5.1945 +
5.1946 + /// <summary>
5.1947 + /// Returns the minimum value in a sequence of nullable
5.1948 + /// <see cref="System.Int32" /> values.
5.1949 + /// </summary>
5.1950 +
5.1951 + public static int? Min(
5.1952 + this IEnumerable<int?> source)
5.1953 + {
5.1954 + if (source == null) throw new ArgumentNullException("source");
5.1955 +
5.1956 + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
5.1957 + }
5.1958 +
5.1959 + /// <summary>
5.1960 + /// Invokes a transform function on each element of a sequence and
5.1961 + /// returns the minimum nullable <see cref="System.Int32" /> value.
5.1962 + /// </summary>
5.1963 +
5.1964 + public static int? Min<TSource>(
5.1965 + this IEnumerable<TSource> source,
5.1966 + Func<TSource, int?> selector)
5.1967 + {
5.1968 + return source.Select(selector).Min();
5.1969 + }
5.1970 +
5.1971 + /// <summary>
5.1972 + /// Returns the maximum value in a sequence of nullable
5.1973 + /// <see cref="System.Int32" /> values.
5.1974 + /// </summary>
5.1975 +
5.1976 + public static int? Max(
5.1977 + this IEnumerable<int?> source)
5.1978 + {
5.1979 + if (source == null) throw new ArgumentNullException("source");
5.1980 +
5.1981 + return MinMaxImpl(source.Where(x => x != null),
5.1982 + null, (max, x) => x == null || (max != null && x.Value < max.Value));
5.1983 + }
5.1984 +
5.1985 + /// <summary>
5.1986 + /// Invokes a transform function on each element of a sequence and
5.1987 + /// returns the maximum nullable <see cref="System.Int32" /> value.
5.1988 + /// </summary>
5.1989 +
5.1990 + public static int? Max<TSource>(
5.1991 + this IEnumerable<TSource> source,
5.1992 + Func<TSource, int?> selector)
5.1993 + {
5.1994 + return source.Select(selector).Max();
5.1995 + }
5.1996 +
5.1997 + /// <summary>
5.1998 + /// Computes the sum of a sequence of nullable <see cref="System.Int64" /> values.
5.1999 + /// </summary>
5.2000 +
5.2001 + public static long Sum(
5.2002 + this IEnumerable<long> source)
5.2003 + {
5.2004 + if (source == null) throw new ArgumentNullException("source");
5.2005 +
5.2006 + long sum = 0;
5.2007 + foreach (var num in source)
5.2008 + sum = checked(sum + num);
5.2009 +
5.2010 + return sum;
5.2011 + }
5.2012 +
5.2013 + /// <summary>
5.2014 + /// Computes the sum of a sequence of nullable <see cref="System.Int64" />
5.2015 + /// values that are obtained by invoking a transform function on
5.2016 + /// each element of the input sequence.
5.2017 + /// </summary>
5.2018 +
5.2019 + public static long Sum<TSource>(
5.2020 + this IEnumerable<TSource> source,
5.2021 + Func<TSource, long> selector)
5.2022 + {
5.2023 + return source.Select(selector).Sum();
5.2024 + }
5.2025 +
5.2026 + /// <summary>
5.2027 + /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values.
5.2028 + /// </summary>
5.2029 +
5.2030 + public static double Average(
5.2031 + this IEnumerable<long> source)
5.2032 + {
5.2033 + if (source == null) throw new ArgumentNullException("source");
5.2034 +
5.2035 + long sum = 0;
5.2036 + long count = 0;
5.2037 +
5.2038 + foreach (var num in source)
5.2039 + checked
5.2040 + {
5.2041 + sum += (long) num;
5.2042 + count++;
5.2043 + }
5.2044 +
5.2045 + if (count == 0)
5.2046 + throw new InvalidOperationException();
5.2047 +
5.2048 + return (double) sum / count;
5.2049 + }
5.2050 +
5.2051 + /// <summary>
5.2052 + /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values
5.2053 + /// that are obtained by invoking a transform function on each
5.2054 + /// element of the input sequence.
5.2055 + /// </summary>
5.2056 +
5.2057 + public static double Average<TSource>(
5.2058 + this IEnumerable<TSource> source,
5.2059 + Func<TSource, long> selector)
5.2060 + {
5.2061 + return source.Select(selector).Average();
5.2062 + }
5.2063 +
5.2064 +
5.2065 + /// <summary>
5.2066 + /// Computes the sum of a sequence of <see cref="System.Int64" /> values.
5.2067 + /// </summary>
5.2068 +
5.2069 + public static long? Sum(
5.2070 + this IEnumerable<long?> source)
5.2071 + {
5.2072 + if (source == null) throw new ArgumentNullException("source");
5.2073 +
5.2074 + long sum = 0;
5.2075 + foreach (var num in source)
5.2076 + sum = checked(sum + (num ?? 0));
5.2077 +
5.2078 + return sum;
5.2079 + }
5.2080 +
5.2081 + /// <summary>
5.2082 + /// Computes the sum of a sequence of <see cref="System.Int64" />
5.2083 + /// values that are obtained by invoking a transform function on
5.2084 + /// each element of the input sequence.
5.2085 + /// </summary>
5.2086 +
5.2087 + public static long? Sum<TSource>(
5.2088 + this IEnumerable<TSource> source,
5.2089 + Func<TSource, long?> selector)
5.2090 + {
5.2091 + return source.Select(selector).Sum();
5.2092 + }
5.2093 +
5.2094 + /// <summary>
5.2095 + /// Computes the average of a sequence of <see cref="System.Int64" /> values.
5.2096 + /// </summary>
5.2097 +
5.2098 + public static double? Average(
5.2099 + this IEnumerable<long?> source)
5.2100 + {
5.2101 + if (source == null) throw new ArgumentNullException("source");
5.2102 +
5.2103 + long sum = 0;
5.2104 + long count = 0;
5.2105 +
5.2106 + foreach (var num in source.Where(n => n != null))
5.2107 + checked
5.2108 + {
5.2109 + sum += (long) num;
5.2110 + count++;
5.2111 + }
5.2112 +
5.2113 + if (count == 0)
5.2114 + return null;
5.2115 +
5.2116 + return (double?) sum / count;
5.2117 + }
5.2118 +
5.2119 + /// <summary>
5.2120 + /// Computes the average of a sequence of <see cref="System.Int64" /> values
5.2121 + /// that are obtained by invoking a transform function on each
5.2122 + /// element of the input sequence.
5.2123 + /// </summary>
5.2124 +
5.2125 + public static double? Average<TSource>(
5.2126 + this IEnumerable<TSource> source,
5.2127 + Func<TSource, long?> selector)
5.2128 + {
5.2129 + return source.Select(selector).Average();
5.2130 + }
5.2131 +
5.2132 + /// <summary>
5.2133 + /// Returns the minimum value in a sequence of nullable
5.2134 + /// <see cref="System.Int64" /> values.
5.2135 + /// </summary>
5.2136 +
5.2137 + public static long? Min(
5.2138 + this IEnumerable<long?> source)
5.2139 + {
5.2140 + if (source == null) throw new ArgumentNullException("source");
5.2141 +
5.2142 + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
5.2143 + }
5.2144 +
5.2145 + /// <summary>
5.2146 + /// Invokes a transform function on each element of a sequence and
5.2147 + /// returns the minimum nullable <see cref="System.Int64" /> value.
5.2148 + /// </summary>
5.2149 +
5.2150 + public static long? Min<TSource>(
5.2151 + this IEnumerable<TSource> source,
5.2152 + Func<TSource, long?> selector)
5.2153 + {
5.2154 + return source.Select(selector).Min();
5.2155 + }
5.2156 +
5.2157 + /// <summary>
5.2158 + /// Returns the maximum value in a sequence of nullable
5.2159 + /// <see cref="System.Int64" /> values.
5.2160 + /// </summary>
5.2161 +
5.2162 + public static long? Max(
5.2163 + this IEnumerable<long?> source)
5.2164 + {
5.2165 + if (source == null) throw new ArgumentNullException("source");
5.2166 +
5.2167 + return MinMaxImpl(source.Where(x => x != null),
5.2168 + null, (max, x) => x == null || (max != null && x.Value < max.Value));
5.2169 + }
5.2170 +
5.2171 + /// <summary>
5.2172 + /// Invokes a transform function on each element of a sequence and
5.2173 + /// returns the maximum nullable <see cref="System.Int64" /> value.
5.2174 + /// </summary>
5.2175 +
5.2176 + public static long? Max<TSource>(
5.2177 + this IEnumerable<TSource> source,
5.2178 + Func<TSource, long?> selector)
5.2179 + {
5.2180 + return source.Select(selector).Max();
5.2181 + }
5.2182 +
5.2183 + /// <summary>
5.2184 + /// Computes the sum of a sequence of nullable <see cref="System.Single" /> values.
5.2185 + /// </summary>
5.2186 +
5.2187 + public static float Sum(
5.2188 + this IEnumerable<float> source)
5.2189 + {
5.2190 + if (source == null) throw new ArgumentNullException("source");
5.2191 +
5.2192 + float sum = 0;
5.2193 + foreach (var num in source)
5.2194 + sum = checked(sum + num);
5.2195 +
5.2196 + return sum;
5.2197 + }
5.2198 +
5.2199 + /// <summary>
5.2200 + /// Computes the sum of a sequence of nullable <see cref="System.Single" />
5.2201 + /// values that are obtained by invoking a transform function on
5.2202 + /// each element of the input sequence.
5.2203 + /// </summary>
5.2204 +
5.2205 + public static float Sum<TSource>(
5.2206 + this IEnumerable<TSource> source,
5.2207 + Func<TSource, float> selector)
5.2208 + {
5.2209 + return source.Select(selector).Sum();
5.2210 + }
5.2211 +
5.2212 + /// <summary>
5.2213 + /// Computes the average of a sequence of nullable <see cref="System.Single" /> values.
5.2214 + /// </summary>
5.2215 +
5.2216 + public static float Average(
5.2217 + this IEnumerable<float> source)
5.2218 + {
5.2219 + if (source == null) throw new ArgumentNullException("source");
5.2220 +
5.2221 + float sum = 0;
5.2222 + long count = 0;
5.2223 +
5.2224 + foreach (var num in source)
5.2225 + checked
5.2226 + {
5.2227 + sum += (float) num;
5.2228 + count++;
5.2229 + }
5.2230 +
5.2231 + if (count == 0)
5.2232 + throw new InvalidOperationException();
5.2233 +
5.2234 + return (float) sum / count;
5.2235 + }
5.2236 +
5.2237 + /// <summary>
5.2238 + /// Computes the average of a sequence of nullable <see cref="System.Single" /> values
5.2239 + /// that are obtained by invoking a transform function on each
5.2240 + /// element of the input sequence.
5.2241 + /// </summary>
5.2242 +
5.2243 + public static float Average<TSource>(
5.2244 + this IEnumerable<TSource> source,
5.2245 + Func<TSource, float> selector)
5.2246 + {
5.2247 + return source.Select(selector).Average();
5.2248 + }
5.2249 +
5.2250 +
5.2251 + /// <summary>
5.2252 + /// Computes the sum of a sequence of <see cref="System.Single" /> values.
5.2253 + /// </summary>
5.2254 +
5.2255 + public static float? Sum(
5.2256 + this IEnumerable<float?> source)
5.2257 + {
5.2258 + if (source == null) throw new ArgumentNullException("source");
5.2259 +
5.2260 + float sum = 0;
5.2261 + foreach (var num in source)
5.2262 + sum = checked(sum + (num ?? 0));
5.2263 +
5.2264 + return sum;
5.2265 + }
5.2266 +
5.2267 + /// <summary>
5.2268 + /// Computes the sum of a sequence of <see cref="System.Single" />
5.2269 + /// values that are obtained by invoking a transform function on
5.2270 + /// each element of the input sequence.
5.2271 + /// </summary>
5.2272 +
5.2273 + public static float? Sum<TSource>(
5.2274 + this IEnumerable<TSource> source,
5.2275 + Func<TSource, float?> selector)
5.2276 + {
5.2277 + return source.Select(selector).Sum();
5.2278 + }
5.2279 +
5.2280 + /// <summary>
5.2281 + /// Computes the average of a sequence of <see cref="System.Single" /> values.
5.2282 + /// </summary>
5.2283 +
5.2284 + public static float? Average(
5.2285 + this IEnumerable<float?> source)
5.2286 + {
5.2287 + if (source == null) throw new ArgumentNullException("source");
5.2288 +
5.2289 + float sum = 0;
5.2290 + long count = 0;
5.2291 +
5.2292 + foreach (var num in source.Where(n => n != null))
5.2293 + checked
5.2294 + {
5.2295 + sum += (float) num;
5.2296 + count++;
5.2297 + }
5.2298 +
5.2299 + if (count == 0)
5.2300 + return null;
5.2301 +
5.2302 + return (float?) sum / count;
5.2303 + }
5.2304 +
5.2305 + /// <summary>
5.2306 + /// Computes the average of a sequence of <see cref="System.Single" /> values
5.2307 + /// that are obtained by invoking a transform function on each
5.2308 + /// element of the input sequence.
5.2309 + /// </summary>
5.2310 +
5.2311 + public static float? Average<TSource>(
5.2312 + this IEnumerable<TSource> source,
5.2313 + Func<TSource, float?> selector)
5.2314 + {
5.2315 + return source.Select(selector).Average();
5.2316 + }
5.2317 +
5.2318 + /// <summary>
5.2319 + /// Returns the minimum value in a sequence of nullable
5.2320 + /// <see cref="System.Single" /> values.
5.2321 + /// </summary>
5.2322 +
5.2323 + public static float? Min(
5.2324 + this IEnumerable<float?> source)
5.2325 + {
5.2326 + if (source == null) throw new ArgumentNullException("source");
5.2327 +
5.2328 + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
5.2329 + }
5.2330 +
5.2331 + /// <summary>
5.2332 + /// Invokes a transform function on each element of a sequence and
5.2333 + /// returns the minimum nullable <see cref="System.Single" /> value.
5.2334 + /// </summary>
5.2335 +
5.2336 + public static float? Min<TSource>(
5.2337 + this IEnumerable<TSource> source,
5.2338 + Func<TSource, float?> selector)
5.2339 + {
5.2340 + return source.Select(selector).Min();
5.2341 + }
5.2342 +
5.2343 + /// <summary>
5.2344 + /// Returns the maximum value in a sequence of nullable
5.2345 + /// <see cref="System.Single" /> values.
5.2346 + /// </summary>
5.2347 +
5.2348 + public static float? Max(
5.2349 + this IEnumerable<float?> source)
5.2350 + {
5.2351 + if (source == null) throw new ArgumentNullException("source");
5.2352 +
5.2353 + return MinMaxImpl(source.Where(x => x != null),
5.2354 + null, (max, x) => x == null || (max != null && x.Value < max.Value));
5.2355 + }
5.2356 +
5.2357 + /// <summary>
5.2358 + /// Invokes a transform function on each element of a sequence and
5.2359 + /// returns the maximum nullable <see cref="System.Single" /> value.
5.2360 + /// </summary>
5.2361 +
5.2362 + public static float? Max<TSource>(
5.2363 + this IEnumerable<TSource> source,
5.2364 + Func<TSource, float?> selector)
5.2365 + {
5.2366 + return source.Select(selector).Max();
5.2367 + }
5.2368 +
5.2369 + /// <summary>
5.2370 + /// Computes the sum of a sequence of nullable <see cref="System.Double" /> values.
5.2371 + /// </summary>
5.2372 +
5.2373 + public static double Sum(
5.2374 + this IEnumerable<double> source)
5.2375 + {
5.2376 + if (source == null) throw new ArgumentNullException("source");
5.2377 +
5.2378 + double sum = 0;
5.2379 + foreach (var num in source)
5.2380 + sum = checked(sum + num);
5.2381 +
5.2382 + return sum;
5.2383 + }
5.2384 +
5.2385 + /// <summary>
5.2386 + /// Computes the sum of a sequence of nullable <see cref="System.Double" />
5.2387 + /// values that are obtained by invoking a transform function on
5.2388 + /// each element of the input sequence.
5.2389 + /// </summary>
5.2390 +
5.2391 + public static double Sum<TSource>(
5.2392 + this IEnumerable<TSource> source,
5.2393 + Func<TSource, double> selector)
5.2394 + {
5.2395 + return source.Select(selector).Sum();
5.2396 + }
5.2397 +
5.2398 + /// <summary>
5.2399 + /// Computes the average of a sequence of nullable <see cref="System.Double" /> values.
5.2400 + /// </summary>
5.2401 +
5.2402 + public static double Average(
5.2403 + this IEnumerable<double> source)
5.2404 + {
5.2405 + if (source == null) throw new ArgumentNullException("source");
5.2406 +
5.2407 + double sum = 0;
5.2408 + long count = 0;
5.2409 +
5.2410 + foreach (var num in source)
5.2411 + checked
5.2412 + {
5.2413 + sum += (double) num;
5.2414 + count++;
5.2415 + }
5.2416 +
5.2417 + if (count == 0)
5.2418 + throw new InvalidOperationException();
5.2419 +
5.2420 + return (double) sum / count;
5.2421 + }
5.2422 +
5.2423 + /// <summary>
5.2424 + /// Computes the average of a sequence of nullable <see cref="System.Double" /> values
5.2425 + /// that are obtained by invoking a transform function on each
5.2426 + /// element of the input sequence.
5.2427 + /// </summary>
5.2428 +
5.2429 + public static double Average<TSource>(
5.2430 + this IEnumerable<TSource> source,
5.2431 + Func<TSource, double> selector)
5.2432 + {
5.2433 + return source.Select(selector).Average();
5.2434 + }
5.2435 +
5.2436 +
5.2437 + /// <summary>
5.2438 + /// Computes the sum of a sequence of <see cref="System.Double" /> values.
5.2439 + /// </summary>
5.2440 +
5.2441 + public static double? Sum(
5.2442 + this IEnumerable<double?> source)
5.2443 + {
5.2444 + if (source == null) throw new ArgumentNullException("source");
5.2445 +
5.2446 + double sum = 0;
5.2447 + foreach (var num in source)
5.2448 + sum = checked(sum + (num ?? 0));
5.2449 +
5.2450 + return sum;
5.2451 + }
5.2452 +
5.2453 + /// <summary>
5.2454 + /// Computes the sum of a sequence of <see cref="System.Double" />
5.2455 + /// values that are obtained by invoking a transform function on
5.2456 + /// each element of the input sequence.
5.2457 + /// </summary>
5.2458 +
5.2459 + public static double? Sum<TSource>(
5.2460 + this IEnumerable<TSource> source,
5.2461 + Func<TSource, double?> selector)
5.2462 + {
5.2463 + return source.Select(selector).Sum();
5.2464 + }
5.2465 +
5.2466 + /// <summary>
5.2467 + /// Computes the average of a sequence of <see cref="System.Double" /> values.
5.2468 + /// </summary>
5.2469 +
5.2470 + public static double? Average(
5.2471 + this IEnumerable<double?> source)
5.2472 + {
5.2473 + if (source == null) throw new ArgumentNullException("source");
5.2474 +
5.2475 + double sum = 0;
5.2476 + long count = 0;
5.2477 +
5.2478 + foreach (var num in source.Where(n => n != null))
5.2479 + checked
5.2480 + {
5.2481 + sum += (double) num;
5.2482 + count++;
5.2483 + }
5.2484 +
5.2485 + if (count == 0)
5.2486 + return null;
5.2487 +
5.2488 + return (double?) sum / count;
5.2489 + }
5.2490 +
5.2491 + /// <summary>
5.2492 + /// Computes the average of a sequence of <see cref="System.Double" /> values
5.2493 + /// that are obtained by invoking a transform function on each
5.2494 + /// element of the input sequence.
5.2495 + /// </summary>
5.2496 +
5.2497 + public static double? Average<TSource>(
5.2498 + this IEnumerable<TSource> source,
5.2499 + Func<TSource, double?> selector)
5.2500 + {
5.2501 + return source.Select(selector).Average();
5.2502 + }
5.2503 +
5.2504 + /// <summary>
5.2505 + /// Returns the minimum value in a sequence of nullable
5.2506 + /// <see cref="System.Double" /> values.
5.2507 + /// </summary>
5.2508 +
5.2509 + public static double? Min(
5.2510 + this IEnumerable<double?> source)
5.2511 + {
5.2512 + if (source == null) throw new ArgumentNullException("source");
5.2513 +
5.2514 + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
5.2515 + }
5.2516 +
5.2517 + /// <summary>
5.2518 + /// Invokes a transform function on each element of a sequence and
5.2519 + /// returns the minimum nullable <see cref="System.Double" /> value.
5.2520 + /// </summary>
5.2521 +
5.2522 + public static double? Min<TSource>(
5.2523 + this IEnumerable<TSource> source,
5.2524 + Func<TSource, double?> selector)
5.2525 + {
5.2526 + return source.Select(selector).Min();
5.2527 + }
5.2528 +
5.2529 + /// <summary>
5.2530 + /// Returns the maximum value in a sequence of nullable
5.2531 + /// <see cref="System.Double" /> values.
5.2532 + /// </summary>
5.2533 +
5.2534 + public static double? Max(
5.2535 + this IEnumerable<double?> source)
5.2536 + {
5.2537 + if (source == null) throw new ArgumentNullException("source");
5.2538 +
5.2539 + return MinMaxImpl(source.Where(x => x != null),
5.2540 + null, (max, x) => x == null || (max != null && x.Value < max.Value));
5.2541 + }
5.2542 +
5.2543 + /// <summary>
5.2544 + /// Invokes a transform function on each element of a sequence and
5.2545 + /// returns the maximum nullable <see cref="System.Double" /> value.
5.2546 + /// </summary>
5.2547 +
5.2548 + public static double? Max<TSource>(
5.2549 + this IEnumerable<TSource> source,
5.2550 + Func<TSource, double?> selector)
5.2551 + {
5.2552 + return source.Select(selector).Max();
5.2553 + }
5.2554 +
5.2555 + /// <summary>
5.2556 + /// Computes the sum of a sequence of nullable <see cref="System.Decimal" /> values.
5.2557 + /// </summary>
5.2558 +
5.2559 + public static decimal Sum(
5.2560 + this IEnumerable<decimal> source)
5.2561 + {
5.2562 + if (source == null) throw new ArgumentNullException("source");
5.2563 +
5.2564 + decimal sum = 0;
5.2565 + foreach (var num in source)
5.2566 + sum = checked(sum + num);
5.2567 +
5.2568 + return sum;
5.2569 + }
5.2570 +
5.2571 + /// <summary>
5.2572 + /// Computes the sum of a sequence of nullable <see cref="System.Decimal" />
5.2573 + /// values that are obtained by invoking a transform function on
5.2574 + /// each element of the input sequence.
5.2575 + /// </summary>
5.2576 +
5.2577 + public static decimal Sum<TSource>(
5.2578 + this IEnumerable<TSource> source,
5.2579 + Func<TSource, decimal> selector)
5.2580 + {
5.2581 + return source.Select(selector).Sum();
5.2582 + }
5.2583 +
5.2584 + /// <summary>
5.2585 + /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values.
5.2586 + /// </summary>
5.2587 +
5.2588 + public static decimal Average(
5.2589 + this IEnumerable<decimal> source)
5.2590 + {
5.2591 + if (source == null) throw new ArgumentNullException("source");
5.2592 +
5.2593 + decimal sum = 0;
5.2594 + long count = 0;
5.2595 +
5.2596 + foreach (var num in source)
5.2597 + checked
5.2598 + {
5.2599 + sum += (decimal) num;
5.2600 + count++;
5.2601 + }
5.2602 +
5.2603 + if (count == 0)
5.2604 + throw new InvalidOperationException();
5.2605 +
5.2606 + return (decimal) sum / count;
5.2607 + }
5.2608 +
5.2609 + /// <summary>
5.2610 + /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values
5.2611 + /// that are obtained by invoking a transform function on each
5.2612 + /// element of the input sequence.
5.2613 + /// </summary>
5.2614 +
5.2615 + public static decimal Average<TSource>(
5.2616 + this IEnumerable<TSource> source,
5.2617 + Func<TSource, decimal> selector)
5.2618 + {
5.2619 + return source.Select(selector).Average();
5.2620 + }
5.2621 +
5.2622 +
5.2623 + /// <summary>
5.2624 + /// Computes the sum of a sequence of <see cref="System.Decimal" /> values.
5.2625 + /// </summary>
5.2626 +
5.2627 + public static decimal? Sum(
5.2628 + this IEnumerable<decimal?> source)
5.2629 + {
5.2630 + if (source == null) throw new ArgumentNullException("source");
5.2631 +
5.2632 + decimal sum = 0;
5.2633 + foreach (var num in source)
5.2634 + sum = checked(sum + (num ?? 0));
5.2635 +
5.2636 + return sum;
5.2637 + }
5.2638 +
5.2639 + /// <summary>
5.2640 + /// Computes the sum of a sequence of <see cref="System.Decimal" />
5.2641 + /// values that are obtained by invoking a transform function on
5.2642 + /// each element of the input sequence.
5.2643 + /// </summary>
5.2644 +
5.2645 + public static decimal? Sum<TSource>(
5.2646 + this IEnumerable<TSource> source,
5.2647 + Func<TSource, decimal?> selector)
5.2648 + {
5.2649 + return source.Select(selector).Sum();
5.2650 + }
5.2651 +
5.2652 + /// <summary>
5.2653 + /// Computes the average of a sequence of <see cref="System.Decimal" /> values.
5.2654 + /// </summary>
5.2655 +
5.2656 + public static decimal? Average(
5.2657 + this IEnumerable<decimal?> source)
5.2658 + {
5.2659 + if (source == null) throw new ArgumentNullException("source");
5.2660 +
5.2661 + decimal sum = 0;
5.2662 + long count = 0;
5.2663 +
5.2664 + foreach (var num in source.Where(n => n != null))
5.2665 + checked
5.2666 + {
5.2667 + sum += (decimal) num;
5.2668 + count++;
5.2669 + }
5.2670 +
5.2671 + if (count == 0)
5.2672 + return null;
5.2673 +
5.2674 + return (decimal?) sum / count;
5.2675 + }
5.2676 +
5.2677 + /// <summary>
5.2678 + /// Computes the average of a sequence of <see cref="System.Decimal" /> values
5.2679 + /// that are obtained by invoking a transform function on each
5.2680 + /// element of the input sequence.
5.2681 + /// </summary>
5.2682 +
5.2683 + public static decimal? Average<TSource>(
5.2684 + this IEnumerable<TSource> source,
5.2685 + Func<TSource, decimal?> selector)
5.2686 + {
5.2687 + return source.Select(selector).Average();
5.2688 + }
5.2689 +
5.2690 + /// <summary>
5.2691 + /// Returns the minimum value in a sequence of nullable
5.2692 + /// <see cref="System.Decimal" /> values.
5.2693 + /// </summary>
5.2694 +
5.2695 + public static decimal? Min(
5.2696 + this IEnumerable<decimal?> source)
5.2697 + {
5.2698 + if (source == null) throw new ArgumentNullException("source");
5.2699 +
5.2700 + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
5.2701 + }
5.2702 +
5.2703 + /// <summary>
5.2704 + /// Invokes a transform function on each element of a sequence and
5.2705 + /// returns the minimum nullable <see cref="System.Decimal" /> value.
5.2706 + /// </summary>
5.2707 +
5.2708 + public static decimal? Min<TSource>(
5.2709 + this IEnumerable<TSource> source,
5.2710 + Func<TSource, decimal?> selector)
5.2711 + {
5.2712 + return source.Select(selector).Min();
5.2713 + }
5.2714 +
5.2715 + /// <summary>
5.2716 + /// Returns the maximum value in a sequence of nullable
5.2717 + /// <see cref="System.Decimal" /> values.
5.2718 + /// </summary>
5.2719 +
5.2720 + public static decimal? Max(
5.2721 + this IEnumerable<decimal?> source)
5.2722 + {
5.2723 + if (source == null) throw new ArgumentNullException("source");
5.2724 +
5.2725 + return MinMaxImpl(source.Where(x => x != null),
5.2726 + null, (max, x) => x == null || (max != null && x.Value < max.Value));
5.2727 + }
5.2728 +
5.2729 + /// <summary>
5.2730 + /// Invokes a transform function on each element of a sequence and
5.2731 + /// returns the maximum nullable <see cref="System.Decimal" /> value.
5.2732 + /// </summary>
5.2733 +
5.2734 + public static decimal? Max<TSource>(
5.2735 + this IEnumerable<TSource> source,
5.2736 + Func<TSource, decimal?> selector)
5.2737 + {
5.2738 + return source.Select(selector).Max();
5.2739 + }
5.2740 + }
5.2741 +}
5.2742 +
5.2743 +// $Id: ExtensionAttribute.cs 898b3d493ed6 2012/04/17 20:09:57 azizatif $
5.2744 +
5.2745 +namespace System.Runtime.CompilerServices
5.2746 +{
5.2747 + /// <remarks>
5.2748 + /// This attribute allows us to define extension methods without
5.2749 + /// requiring .NET Framework 3.5. For more information, see the section,
5.2750 + /// <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx#S7">Extension Methods in .NET Framework 2.0 Apps</a>,
5.2751 + /// of <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx">Basic Instincts: Extension Methods</a>
5.2752 + /// column in <a href="http://msdn.microsoft.com/msdnmag/">MSDN Magazine</a>,
5.2753 + /// issue <a href="http://msdn.microsoft.com/en-us/magazine/cc135410.aspx">Nov 2007</a>.
5.2754 + /// </remarks>
5.2755 +
5.2756 + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
5.2757 + sealed partial class ExtensionAttribute : Attribute { }
5.2758 +}
5.2759 +
5.2760 +// $Id: Func.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
5.2761 +
5.2762 +namespace System
5.2763 +{
5.2764 +#if LINQBRIDGE_LIB
5.2765 + public delegate TResult Func<out TResult>();
5.2766 + public delegate TResult Func<in T, out TResult>(T a);
5.2767 + public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
5.2768 + public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
5.2769 + public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
5.2770 +#else
5.2771 + delegate TResult Func<TResult>();
5.2772 + delegate TResult Func<T, TResult>(T a);
5.2773 + delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
5.2774 + delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
5.2775 + delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
5.2776 +#endif
5.2777 +}
5.2778 +
5.2779 +// $Id: IGrouping.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
5.2780 +
5.2781 +namespace System.Linq
5.2782 +{
5.2783 + #region Imports
5.2784 +
5.2785 + using System.Collections.Generic;
5.2786 +
5.2787 + #endregion
5.2788 +
5.2789 + /// <summary>
5.2790 + /// Represents a collection of objects that have a common key.
5.2791 + /// </summary>
5.2792 +
5.2793 + partial interface IGrouping<out TKey, TElement> : IEnumerable<TElement>
5.2794 + {
5.2795 + /// <summary>
5.2796 + /// Gets the key of the <see cref="IGrouping{TKey,TElement}" />.
5.2797 + /// </summary>
5.2798 +
5.2799 + TKey Key { get; }
5.2800 + }
5.2801 +}
5.2802 +
5.2803 +// $Id: ILookup.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
5.2804 +
5.2805 +namespace System.Linq
5.2806 +{
5.2807 + using System.Collections.Generic;
5.2808 +
5.2809 + /// <summary>
5.2810 + /// Defines an indexer, size property, and Boolean search method for
5.2811 + /// data structures that map keys to <see cref="IEnumerable{T}"/>
5.2812 + /// sequences of values.
5.2813 + /// </summary>
5.2814 +
5.2815 + partial interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>
5.2816 + {
5.2817 + bool Contains(TKey key);
5.2818 + int Count { get; }
5.2819 + IEnumerable<TElement> this[TKey key] { get; }
5.2820 + }
5.2821 +}
5.2822 +
5.2823 +// $Id: Internal.cs 1567e00f1a20 2012/04/17 16:09:51 azizatif $
5.2824 +
5.2825 +namespace LinqBridge
5.2826 +{
5.2827 + #region Imports
5.2828 +
5.2829 + using System;
5.2830 + using System.Collections.Generic;
5.2831 +
5.2832 + #endregion
5.2833 +
5.2834 + /// <remarks>
5.2835 + /// This type is not intended to be used directly from user code.
5.2836 + /// It may be removed or changed in a future version without notice.
5.2837 + /// </remarks>
5.2838 +
5.2839 + sealed class DelegatingComparer<T> : IComparer<T>
5.2840 + {
5.2841 + private readonly Func<T, T, int> _comparer;
5.2842 +
5.2843 + public DelegatingComparer(Func<T, T, int> comparer)
5.2844 + {
5.2845 + if (comparer == null) throw new ArgumentNullException("comparer");
5.2846 + _comparer = comparer;
5.2847 + }
5.2848 +
5.2849 + public int Compare(T x, T y) { return _comparer(x, y); }
5.2850 + }
5.2851 +
5.2852 + /// <remarks>
5.2853 + /// This type is not intended to be used directly from user code.
5.2854 + /// It may be removed or changed in a future version without notice.
5.2855 + /// </remarks>
5.2856 +
5.2857 + struct Key<T>
5.2858 + {
5.2859 + public Key(T value) : this() { Value = value; }
5.2860 + public T Value { get; private set; }
5.2861 + }
5.2862 +
5.2863 + /// <remarks>
5.2864 + /// This type is not intended to be used directly from user code.
5.2865 + /// It may be removed or changed in a future version without notice.
5.2866 + /// </remarks>
5.2867 +
5.2868 + sealed class KeyComparer<T> : IEqualityComparer<Key<T>>
5.2869 + {
5.2870 + private readonly IEqualityComparer<T> _innerComparer;
5.2871 +
5.2872 + public KeyComparer(IEqualityComparer<T> innerComparer)
5.2873 + {
5.2874 + _innerComparer = innerComparer ?? EqualityComparer<T>.Default;
5.2875 + }
5.2876 +
5.2877 + public bool Equals(Key<T> x, Key<T> y)
5.2878 + {
5.2879 + return _innerComparer.Equals(x.Value, y.Value);
5.2880 + }
5.2881 +
5.2882 + public int GetHashCode(Key<T> obj)
5.2883 + {
5.2884 + return obj.Value == null ? 0 : _innerComparer.GetHashCode(obj.Value);
5.2885 + }
5.2886 + }
5.2887 +}
5.2888 +
5.2889 +// $Id: IOrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
5.2890 +
5.2891 +namespace System.Linq
5.2892 +{
5.2893 + using System.Collections.Generic;
5.2894 +
5.2895 + /// <summary>
5.2896 + /// Represents a sorted sequence.
5.2897 + /// </summary>
5.2898 +
5.2899 + partial interface IOrderedEnumerable<TElement> : IEnumerable<TElement>
5.2900 + {
5.2901 + /// <summary>
5.2902 + /// Performs a subsequent ordering on the elements of an
5.2903 + /// <see cref="IOrderedEnumerable{T}"/> according to a key.
5.2904 + /// </summary>
5.2905 +
5.2906 + IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(
5.2907 + Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
5.2908 + }
5.2909 +}
5.2910 +
5.2911 +// $Id: Lookup.cs c08984d432b1 2012/04/17 16:05:19 azizatif $
5.2912 +
5.2913 +namespace System.Linq
5.2914 +{
5.2915 + #region Imports
5.2916 +
5.2917 + using System;
5.2918 + using System.Collections;
5.2919 + using System.Collections.Generic;
5.2920 + using IEnumerable=System.Collections.IEnumerable;
5.2921 + using LinqBridge;
5.2922 +
5.2923 + #endregion
5.2924 +
5.2925 + /// <summary>
5.2926 + /// Represents a collection of keys each mapped to one or more values.
5.2927 + /// </summary>
5.2928 +
5.2929 + internal sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement>
5.2930 + {
5.2931 + private readonly Dictionary<Key<TKey>, IGrouping<TKey, TElement>> _map;
5.2932 + private readonly List<Key<TKey>> _orderedKeys; // remember order of insertion
5.2933 +
5.2934 + internal Lookup(IEqualityComparer<TKey> comparer)
5.2935 + {
5.2936 + _map = new Dictionary<Key<TKey>, IGrouping<TKey, TElement>>(new KeyComparer<TKey>(comparer));
5.2937 + _orderedKeys = new List<Key<TKey>>();
5.2938 + }
5.2939 +
5.2940 + internal void Add(IGrouping<TKey, TElement> item)
5.2941 + {
5.2942 + var key = new Key<TKey>(item.Key);
5.2943 + _map.Add(key, item);
5.2944 + _orderedKeys.Add(key);
5.2945 + }
5.2946 +
5.2947 + internal IEnumerable<TElement> Find(TKey key)
5.2948 + {
5.2949 + IGrouping<TKey, TElement> grouping;
5.2950 + return _map.TryGetValue(new Key<TKey>(key), out grouping) ? grouping : null;
5.2951 + }
5.2952 +
5.2953 + /// <summary>
5.2954 + /// Gets the number of key/value collection pairs in the <see cref="Lookup{TKey,TElement}" />.
5.2955 + /// </summary>
5.2956 +
5.2957 + public int Count
5.2958 + {
5.2959 + get { return _map.Count; }
5.2960 + }
5.2961 +
5.2962 + /// <summary>
5.2963 + /// Gets the collection of values indexed by the specified key.
5.2964 + /// </summary>
5.2965 +
5.2966 + public IEnumerable<TElement> this[TKey key]
5.2967 + {
5.2968 + get
5.2969 + {
5.2970 + IGrouping<TKey, TElement> result;
5.2971 + return _map.TryGetValue(new Key<TKey>(key), out result) ? result : Enumerable.Empty<TElement>();
5.2972 + }
5.2973 + }
5.2974 +
5.2975 + /// <summary>
5.2976 + /// Determines whether a specified key is in the <see cref="Lookup{TKey,TElement}" />.
5.2977 + /// </summary>
5.2978 +
5.2979 + public bool Contains(TKey key)
5.2980 + {
5.2981 + return _map.ContainsKey(new Key<TKey>(key));
5.2982 + }
5.2983 +
5.2984 + /// <summary>
5.2985 + /// Applies a transform function to each key and its associated
5.2986 + /// values and returns the results.
5.2987 + /// </summary>
5.2988 +
5.2989 + public IEnumerable<TResult> ApplyResultSelector<TResult>(
5.2990 + Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
5.2991 + {
5.2992 + if (resultSelector == null)
5.2993 + throw new ArgumentNullException("resultSelector");
5.2994 +
5.2995 + foreach (var pair in _map)
5.2996 + yield return resultSelector(pair.Key.Value, pair.Value);
5.2997 + }
5.2998 +
5.2999 + /// <summary>
5.3000 + /// Returns a generic enumerator that iterates through the <see cref="Lookup{TKey,TElement}" />.
5.3001 + /// </summary>
5.3002 +
5.3003 + public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator()
5.3004 + {
5.3005 + foreach (var key in _orderedKeys)
5.3006 + yield return _map[key];
5.3007 + }
5.3008 +
5.3009 + IEnumerator IEnumerable.GetEnumerator()
5.3010 + {
5.3011 + return GetEnumerator();
5.3012 + }
5.3013 + }
5.3014 +}
5.3015 +
5.3016 +// $Id: OrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
5.3017 +
5.3018 +namespace LinqBridge
5.3019 +{
5.3020 + #region Imports
5.3021 +
5.3022 + using System;
5.3023 + using System.Collections;
5.3024 + using System.Collections.Generic;
5.3025 + using System.Diagnostics;
5.3026 + using System.Linq;
5.3027 +
5.3028 + #endregion
5.3029 +
5.3030 + internal sealed class OrderedEnumerable<T, K> : IOrderedEnumerable<T>
5.3031 + {
5.3032 + private readonly IEnumerable<T> _source;
5.3033 + private readonly Func<T[], IComparer<int>, IComparer<int>> _comparerComposer;
5.3034 +
5.3035 + public OrderedEnumerable(IEnumerable<T> source,
5.3036 + Func<T, K> keySelector, IComparer<K> comparer, bool descending) :
5.3037 + this(source, (_, next) => next, keySelector, comparer, descending) {}
5.3038 +
5.3039 + private OrderedEnumerable(IEnumerable<T> source,
5.3040 + Func<T[], IComparer<int>, IComparer<int>> parent,
5.3041 + Func<T, K> keySelector, IComparer<K> comparer, bool descending)
5.3042 + {
5.3043 + if (source == null) throw new ArgumentNullException("source");
5.3044 + if (keySelector == null) throw new ArgumentNullException("keySelector");
5.3045 + Debug.Assert(parent != null);
5.3046 +
5.3047 + _source = source;
5.3048 +
5.3049 + comparer = comparer ?? Comparer<K>.Default;
5.3050 + var direction = descending ? -1 : 1;
5.3051 +
5.3052 + _comparerComposer = (items, next) =>
5.3053 + {
5.3054 + Debug.Assert(items != null);
5.3055 + Debug.Assert(next != null);
5.3056 +
5.3057 + var keys = new K[items.Length];
5.3058 + for (var i = 0; i < items.Length; i++)
5.3059 + keys[i] = keySelector(items[i]);
5.3060 +
5.3061 + return parent(items, new DelegatingComparer<int>((i, j) =>
5.3062 + {
5.3063 + var result = direction * comparer.Compare(keys[i], keys[j]);
5.3064 + return result != 0 ? result : next.Compare(i, j);
5.3065 + }));
5.3066 + };
5.3067 + }
5.3068 +
5.3069 + public IOrderedEnumerable<T> CreateOrderedEnumerable<KK>(
5.3070 + Func<T, KK> keySelector, IComparer<KK> comparer, bool descending)
5.3071 + {
5.3072 + return new OrderedEnumerable<T, KK>(_source, _comparerComposer, keySelector, comparer, descending);
5.3073 + }
5.3074 +
5.3075 + public IEnumerator<T> GetEnumerator()
5.3076 + {
5.3077 + //
5.3078 + // Sort using Array.Sort but docs say that it performs an
5.3079 + // unstable sort. LINQ, on the other hand, says OrderBy performs
5.3080 + // a stable sort. Use the item position then as a tie
5.3081 + // breaker when all keys compare equal, thus making the sort
5.3082 + // stable.
5.3083 + //
5.3084 +
5.3085 + var items = _source.ToArray();
5.3086 + var positionComparer = new DelegatingComparer<int>((i, j) => i.CompareTo(j));
5.3087 + var comparer = _comparerComposer(items, positionComparer);
5.3088 + var keys = new int[items.Length];
5.3089 + for (var i = 0; i < keys.Length; i++)
5.3090 + keys[i] = i;
5.3091 + Array.Sort(keys, items, comparer);
5.3092 + return ((IEnumerable<T>) items).GetEnumerator();
5.3093 + }
5.3094 +
5.3095 + IEnumerator IEnumerable.GetEnumerator()
5.3096 + {
5.3097 + return GetEnumerator();
5.3098 + }
5.3099 + }
5.3100 +}
5.3101 +
5.3102 +// $Id: Action.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
5.3103 +
5.3104 +namespace System
5.3105 +{
5.3106 +#if LINQBRIDGE_LIB
5.3107 + public delegate void Action();
5.3108 + public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
5.3109 + public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3);
5.3110 + public delegate void Action<in T1, in T2, in T3, in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
5.3111 +#else
5.3112 + delegate void Action();
5.3113 + delegate void Action<T1, T2>(T1 arg1, T2 arg2);
5.3114 + delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
5.3115 + delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
5.3116 +#endif
5.3117 +}
5.3118 +
6.1 --- a/External/OxyPlot/OxyPlot/OxyPlot.csproj Sat Jun 08 16:53:22 2013 +0000
6.2 +++ b/External/OxyPlot/OxyPlot/OxyPlot.csproj Sat Jun 08 17:06:00 2013 +0000
6.3 @@ -9,41 +9,39 @@
6.4 <AppDesignerFolder>Properties</AppDesignerFolder>
6.5 <RootNamespace>OxyPlot</RootNamespace>
6.6 <AssemblyName>OxyPlot</AssemblyName>
6.7 - <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
6.8 + <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
6.9 <FileAlignment>512</FileAlignment>
6.10 - <TargetFrameworkProfile>Client</TargetFrameworkProfile>
6.11 + <TargetFrameworkProfile>
6.12 + </TargetFrameworkProfile>
6.13 </PropertyGroup>
6.14 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
6.15 <DebugSymbols>true</DebugSymbols>
6.16 <DebugType>full</DebugType>
6.17 <Optimize>false</Optimize>
6.18 - <OutputPath>bin\Debug\</OutputPath>
6.19 - <DefineConstants>DEBUG;TRACE</DefineConstants>
6.20 + <OutputPath>Bin\Debug\</OutputPath>
6.21 + <DefineConstants>TRACE;DEBUG;LINQBRIDGE_LIB</DefineConstants>
6.22 <ErrorReport>prompt</ErrorReport>
6.23 <WarningLevel>4</WarningLevel>
6.24 </PropertyGroup>
6.25 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
6.26 <DebugType>pdbonly</DebugType>
6.27 <Optimize>true</Optimize>
6.28 - <OutputPath>..\..\Output\NET40x\</OutputPath>
6.29 - <DefineConstants>TRACE</DefineConstants>
6.30 + <OutputPath>Bin\Release\</OutputPath>
6.31 + <DefineConstants>TRACE;LINQBRIDGE_LIB</DefineConstants>
6.32 <ErrorReport>prompt</ErrorReport>
6.33 <WarningLevel>4</WarningLevel>
6.34 - <DocumentationFile>..\..\Output\NET40x\OxyPlot.XML</DocumentationFile>
6.35 + <DocumentationFile>
6.36 + </DocumentationFile>
6.37 </PropertyGroup>
6.38 <PropertyGroup>
6.39 <SignAssembly>true</SignAssembly>
6.40 </PropertyGroup>
6.41 <PropertyGroup>
6.42 - <AssemblyOriginatorKeyFile>OxyPlot.snk</AssemblyOriginatorKeyFile>
6.43 + <AssemblyOriginatorKeyFile>
6.44 + </AssemblyOriginatorKeyFile>
6.45 </PropertyGroup>
6.46 <ItemGroup>
6.47 <Reference Include="System" />
6.48 - <Reference Include="System.Core" />
6.49 - <Reference Include="System.Xml.Linq" />
6.50 - <Reference Include="System.Data.DataSetExtensions" />
6.51 - <Reference Include="Microsoft.CSharp" />
6.52 - <Reference Include="System.Data" />
6.53 <Reference Include="System.Xml" />
6.54 </ItemGroup>
6.55 <ItemGroup>
6.56 @@ -95,6 +93,7 @@
6.57 <Compile Include="Foundation\IDataPoint.cs" />
6.58 <Compile Include="Foundation\ReflectionHelper.cs" />
6.59 <Compile Include="Foundation\ScreenPointHelper.cs" />
6.60 + <Compile Include="LinqBridge.cs" />
6.61 <Compile Include="Manipulators\ZoomManipulator.cs" />
6.62 <Compile Include="Manipulators\ZoomStepManipulator.cs" />
6.63 <Compile Include="Manipulators\ResetManipulator.cs" />
6.64 @@ -224,7 +223,6 @@
6.65 <None Include="ClassDiagrams\Series.cd" />
6.66 <None Include="ClassDiagrams\PlotModel.cd" />
6.67 <None Include="ClassDiagrams\Reporting.cd" />
6.68 - <None Include="OxyPlot.snk" />
6.69 </ItemGroup>
6.70 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
6.71 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
7.1 Binary file External/OxyPlot/OxyPlot/OxyPlot.snk has changed
8.1 --- a/External/OxyPlot/OxyPlot/Series/DataSeries.cs Sat Jun 08 16:53:22 2013 +0000
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,391 +0,0 @@
8.4 -// --------------------------------------------------------------------------------------------------------------------
8.5 -// <copyright file="DataSeries.cs" company="OxyPlot">
8.6 -// The MIT License (MIT)
8.7 -//
8.8 -// Copyright (c) 2012 Oystein Bjorke
8.9 -//
8.10 -// Permission is hereby granted, free of charge, to any person obtaining a
8.11 -// copy of this software and associated documentation files (the
8.12 -// "Software"), to deal in the Software without restriction, including
8.13 -// without limitation the rights to use, copy, modify, merge, publish,
8.14 -// distribute, sublicense, and/or sell copies of the Software, and to
8.15 -// permit persons to whom the Software is furnished to do so, subject to
8.16 -// the following conditions:
8.17 -//
8.18 -// The above copyright notice and this permission notice shall be included
8.19 -// in all copies or substantial portions of the Software.
8.20 -//
8.21 -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8.22 -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8.23 -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8.24 -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
8.25 -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
8.26 -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
8.27 -// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8.28 -// </copyright>
8.29 -// <summary>
8.30 -// DataPointProvider interface.
8.31 -// </summary>
8.32 -// --------------------------------------------------------------------------------------------------------------------
8.33 -using System;
8.34 -using System.Collections;
8.35 -using System.Collections.Generic;
8.36 -using System.Collections.ObjectModel;
8.37 -using System.ComponentModel;
8.38 -using System.Linq;
8.39 -using System.Reflection;
8.40 -
8.41 -namespace OxyPlot
8.42 -{
8.43 - /// <summary>
8.44 - /// DataPointProvider interface.
8.45 - /// </summary>
8.46 - public interface IDataPointProvider
8.47 - {
8.48 - /// <summary>
8.49 - /// Gets the data point.
8.50 - /// </summary>
8.51 - /// <returns></returns>
8.52 - DataPoint GetDataPoint();
8.53 - }
8.54 -
8.55 - public abstract class DataSeries : PlotSeriesBase
8.56 - {
8.57 - protected IList<DataPoint> points;
8.58 -
8.59 - protected DataSeries()
8.60 - {
8.61 - points = new Collection<DataPoint>();
8.62 - DataFieldX = "X";
8.63 - DataFieldY = "Y";
8.64 - CanTrackerInterpolatePoints = false;
8.65 - }
8.66 -
8.67 - /// <summary>
8.68 - /// Gets or sets the items source.
8.69 - /// </summary>
8.70 - /// <value>The items source.</value>
8.71 - public IEnumerable ItemsSource { get; set; }
8.72 -
8.73 - /// <summary>
8.74 - /// Gets or sets the data field X.
8.75 - /// </summary>
8.76 - /// <value>The data field X.</value>
8.77 - public string DataFieldX { get; set; }
8.78 -
8.79 - /// <summary>
8.80 - /// Gets or sets the data field Y.
8.81 - /// </summary>
8.82 - /// <value>The data field Y.</value>
8.83 - public string DataFieldY { get; set; }
8.84 -
8.85 - /// <summary>
8.86 - /// Gets or sets the mapping deleagte.
8.87 - /// Example: series1.Mapping = item => new DataPoint(((MyType)item).Time,((MyType)item).Value);
8.88 - /// </summary>
8.89 - /// <value>The mapping.</value>
8.90 - public Func<object, DataPoint> Mapping { get; set; }
8.91 -
8.92 - /// <summary>
8.93 - /// Gets or sets the points.
8.94 - /// </summary>
8.95 - /// <value>The points.</value>
8.96 - [Browsable(false)]
8.97 - public IList<DataPoint> Points
8.98 - {
8.99 - get { return points; }
8.100 - set { points = value; }
8.101 - }
8.102 -
8.103 - /// <summary>
8.104 - /// Gets or sets a value indicating whether this <see cref = "DataSeries" /> is smooth.
8.105 - /// </summary>
8.106 - /// <value><c>true</c> if smooth; otherwise, <c>false</c>.</value>
8.107 - public bool Smooth { get; set; }
8.108 -
8.109 - public override void UpdateData()
8.110 - {
8.111 - if (ItemsSource == null)
8.112 - {
8.113 - return;
8.114 - }
8.115 -
8.116 - points.Clear();
8.117 -
8.118 - // Use the mapping to generate the points
8.119 - if (Mapping != null)
8.120 - {
8.121 - foreach (var item in ItemsSource)
8.122 - {
8.123 - points.Add(Mapping(item));
8.124 - }
8.125 - }
8.126 -
8.127 - // Get DataPoints from the items in ItemsSource
8.128 - // if they implement IDataPointProvider
8.129 - // If DataFields are set, this is not used
8.130 - if (DataFieldX == null || DataFieldY == null)
8.131 - {
8.132 - foreach (var item in ItemsSource)
8.133 - {
8.134 - var idpp = item as IDataPointProvider;
8.135 - if (idpp == null)
8.136 - {
8.137 - continue;
8.138 - }
8.139 -
8.140 - points.Add(idpp.GetDataPoint());
8.141 - }
8.142 -
8.143 - return;
8.144 - }
8.145 -
8.146 - // TODO: is there a better way to do this?
8.147 - // http://msdn.microsoft.com/en-us/library/bb613546.aspx
8.148 -
8.149 - // Using reflection on DataFieldX and DataFieldY
8.150 - AddDataPoints(points, ItemsSource, DataFieldX, DataFieldY);
8.151 - }
8.152 -
8.153 - /// <summary>
8.154 - /// Converts the value of the specified object to a double precision floating point number.
8.155 - /// DateTime objects are converted using DateTimeAxis.ToDouble
8.156 - /// TimeSpan objects are converted using TimeSpanAxis.ToDouble
8.157 - /// </summary>
8.158 - /// <param name="value">The value.</param>
8.159 - /// <returns></returns>
8.160 - protected virtual double ToDouble(object value)
8.161 - {
8.162 - if (value is DateTime)
8.163 - {
8.164 - return DateTimeAxis.ToDouble((DateTime)value);
8.165 - }
8.166 -
8.167 - if (value is TimeSpan)
8.168 - {
8.169 - return ((TimeSpan)value).TotalSeconds;
8.170 - }
8.171 -
8.172 - return Convert.ToDouble(value);
8.173 - }
8.174 -
8.175 - /// <summary>
8.176 - /// Updates the max/min from the datapoints.
8.177 - /// </summary>
8.178 - public override void UpdateMaxMin()
8.179 - {
8.180 - base.UpdateMaxMin();
8.181 - InternalUpdateMaxMin(points);
8.182 - }
8.183 -
8.184 - /// <summary>
8.185 - /// Gets the point in the dataset that is nearest the specified point.
8.186 - /// </summary>
8.187 - /// <param name = "point">The point.</param>
8.188 - /// <param name = "dpn">The nearest point (data coordinates).</param>
8.189 - /// <param name = "spn">The nearest point (screen coordinates).</param>
8.190 - /// <returns></returns>
8.191 - public override bool GetNearestPoint(ScreenPoint point, out DataPoint dpn, out ScreenPoint spn)
8.192 - {
8.193 - spn = default(ScreenPoint);
8.194 - dpn = default(DataPoint);
8.195 -
8.196 - double minimumDistance = double.MaxValue;
8.197 - foreach (var p in points)
8.198 - {
8.199 - var sp = AxisBase.Transform(p, XAxis, YAxis);
8.200 - double dx = sp.x - point.x;
8.201 - double dy = sp.y - point.y;
8.202 - double d2 = dx * dx + dy * dy;
8.203 -
8.204 - if (d2 < minimumDistance)
8.205 - {
8.206 - dpn = p;
8.207 - spn = sp;
8.208 - minimumDistance = d2;
8.209 - }
8.210 - }
8.211 -
8.212 - return minimumDistance < double.MaxValue;
8.213 - }
8.214 -
8.215 - /// <summary>
8.216 - /// Gets the point on the curve that is nearest the specified point.
8.217 - /// </summary>
8.218 - /// <param name = "point">The point.</param>
8.219 - /// <param name = "dpn">The nearest point (data coordinates).</param>
8.220 - /// <param name = "spn">The nearest point (screen coordinates).</param>
8.221 - /// <returns></returns>
8.222 - public override bool GetNearestInterpolatedPoint(ScreenPoint point, out DataPoint dpn, out ScreenPoint spn)
8.223 - {
8.224 - spn = default(ScreenPoint);
8.225 - dpn = default(DataPoint);
8.226 -
8.227 - // http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
8.228 - double minimumDistance = double.MaxValue;
8.229 -
8.230 - for (int i = 0; i + 1 < points.Count; i++)
8.231 - {
8.232 - var p1 = points[i];
8.233 - var p2 = points[i + 1];
8.234 - var sp1 = AxisBase.Transform(p1, XAxis, YAxis);
8.235 - var sp2 = AxisBase.Transform(p2, XAxis, YAxis);
8.236 -
8.237 - double sp21X = sp2.x - sp1.x;
8.238 - double sp21Y = sp2.y - sp1.y;
8.239 - double u1 = (point.x - sp1.x) * sp21X + (point.y - sp1.y) * sp21Y;
8.240 - double u2 = sp21X * sp21X + sp21Y * sp21Y;
8.241 - double ds = sp21X * sp21X + sp21Y * sp21Y;
8.242 -
8.243 - if (ds < 4)
8.244 - {
8.245 - // if the points are very close, we can get numerical problems, just use the first point...
8.246 - u1 = 0; u2 = 1;
8.247 - }
8.248 -
8.249 - if (u2 == 0)
8.250 - {
8.251 - continue; // P1 && P2 coincident
8.252 - }
8.253 -
8.254 - double u = u1 / u2;
8.255 - if (u < 0 || u > 1)
8.256 - {
8.257 - continue; // outside line
8.258 - }
8.259 -
8.260 - double sx = sp1.x + u * sp21X;
8.261 - double sy = sp1.y + u * sp21Y;
8.262 -
8.263 - double dx = point.x - sx;
8.264 - double dy = point.y - sy;
8.265 - double distance = dx * dx + dy * dy;
8.266 -
8.267 - if (distance < minimumDistance)
8.268 - {
8.269 - double px = p1.x + u * (p2.x - p1.x);
8.270 - double py = p1.y + u * (p2.y - p1.y);
8.271 - dpn = new DataPoint(px, py);
8.272 - spn = new ScreenPoint(sx, sy);
8.273 - minimumDistance = distance;
8.274 - }
8.275 - }
8.276 -
8.277 - return minimumDistance < double.MaxValue;
8.278 - }
8.279 -
8.280 - protected void AddDataPoints(ICollection<DataPoint> points, IEnumerable itemsSource, string dataFieldX, string dataFieldY)
8.281 - {
8.282 - PropertyInfo pix = null;
8.283 - PropertyInfo piy = null;
8.284 - Type t = null;
8.285 -
8.286 - foreach (var o in itemsSource)
8.287 - {
8.288 - if (pix == null || o.GetType() != t)
8.289 - {
8.290 - t = o.GetType();
8.291 - pix = t.GetProperty(dataFieldX);
8.292 - piy = t.GetProperty(dataFieldY);
8.293 - if (pix == null)
8.294 - {
8.295 - throw new InvalidOperationException(string.Format("Could not find data field {0} on type {1}",
8.296 - DataFieldX, t));
8.297 - }
8.298 -
8.299 - if (piy == null)
8.300 - {
8.301 - throw new InvalidOperationException(string.Format("Could not find data field {0} on type {1}",
8.302 - DataFieldY, t));
8.303 - }
8.304 - }
8.305 -
8.306 - var x = ToDouble(pix.GetValue(o, null));
8.307 - var y = ToDouble(piy.GetValue(o, null));
8.308 -
8.309 - var pp = new DataPoint(x, y);
8.310 - points.Add(pp);
8.311 - }
8.312 - }
8.313 -
8.314 - /// <summary>
8.315 - /// Updates the Max/Min limits from the specified point list.
8.316 - /// </summary>
8.317 - /// <param name="pts">The PTS.</param>
8.318 - protected void InternalUpdateMaxMin(IList<DataPoint> pts)
8.319 - {
8.320 - if (pts == null || pts.Count == 0)
8.321 - {
8.322 - return;
8.323 - }
8.324 -
8.325 - double minx = MinX;
8.326 - double miny = MinY;
8.327 - double maxx = MaxX;
8.328 - double maxy = MaxY;
8.329 -
8.330 - foreach (var pt in pts)
8.331 - {
8.332 - if (!IsValidPoint(pt,XAxis,YAxis))
8.333 - continue;
8.334 - if (pt.x < minx || double.IsNaN(minx)) minx = pt.x;
8.335 - if (pt.x > maxx || double.IsNaN(maxx)) maxx = pt.x;
8.336 - if (pt.y < miny || double.IsNaN(miny)) miny = pt.y;
8.337 - if (pt.y > maxy || double.IsNaN(maxy)) maxy = pt.y;
8.338 - }
8.339 -
8.340 - MinX = minx;
8.341 - MinY = miny;
8.342 - MaxX = maxx;
8.343 - MaxY = maxy;
8.344 -
8.345 - XAxis.Include(MinX);
8.346 - XAxis.Include(MaxX);
8.347 - YAxis.Include(MinY);
8.348 - YAxis.Include(MaxY);
8.349 - }
8.350 -
8.351 - /// <summary>
8.352 - /// Gets the value from the specified X.
8.353 - /// </summary>
8.354 - /// <param name = "x">The x.</param>
8.355 - /// <returns></returns>
8.356 - public double? GetValueFromX(double x)
8.357 - {
8.358 - for (int i = 0; i + 1 < points.Count; i++)
8.359 - {
8.360 - if (IsBetween(x, points[i].x, points[i + 1].x))
8.361 - {
8.362 - return points[i].y +
8.363 - (points[i + 1].y - points[i].y) /
8.364 - (points[i + 1].x - points[i].x) * (x - points[i].x);
8.365 - }
8.366 - }
8.367 -
8.368 - return null;
8.369 - }
8.370 -
8.371 - private static bool IsBetween(double x, double x0, double x1)
8.372 - {
8.373 - if (x >= x0 && x <= x1)
8.374 - {
8.375 - return true;
8.376 - }
8.377 -
8.378 - if (x >= x1 && x <= x0)
8.379 - {
8.380 - return true;
8.381 - }
8.382 -
8.383 - return false;
8.384 - }
8.385 -
8.386 - public virtual bool IsValidPoint(DataPoint pt, IAxis xAxis, IAxis yAxis)
8.387 - {
8.388 - return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X)
8.389 - && !double.IsNaN(pt.Y) && !double.IsInfinity(pt.Y)
8.390 - && (xAxis!=null && xAxis.IsValidValue(pt.X))
8.391 - && (yAxis!=null && yAxis.IsValidValue(pt.Y));
8.392 - }
8.393 - }
8.394 -}
8.395 \ No newline at end of file