Linq.IndexRange: The package to enable C# 8.0 index and range featues for LINQ and IEnumerable<T> types

LINQ operators to enable C# 8.0 index and range new features working with LINQ queries and any type that implements IEnumerable<T>.

dotnet add package Linq.IndexRange
var element = source1.ElementAt(index: `5);
var elements = source2.ElementsIn(range: 10..^10); // or Slice(10..^10)
var query1 = Enumerable.Range(10..20).Select().Where();
var query2 = (10..20).AsEnumerable().Select().Where();

Proposed these APIs to .NET Core dotnet/corefx/#35552.

Problem

Index/range are language level features. However, currently (v3.0.0-preview2/SDK 3.0.100-preview-010184), they

  • only work with array, not other types like List<T>
  • are compiled to array copy, apparently no deferred execution.

Rationale and usage

The goals of these LINQ APIs are:

  • Use index to locate an element in sequence.
  • Use range to slice a sequence. The usage should be consistent with array, but with deferred execution.
  • Use range to start fluent LINQ query.

This enables index and range langaguge features to work with any type that implements IEnumerable<T>.

LINQ already has ElementAt(int index) and ElementAtOrDefault(int index) query operator. It would be natural to have a overload for System.Index: ElementAt(Index index) and ElementAtOrDefault(Index index), and a new method ElementsIn(Range range) (or Slice(Range)), so that LINQ can seamlessly work with C# 8.0:

Index index = ...;
var element1 = source1.ElementAt(index);
var element2 = source2.ElementAtOrDefault(^5);
Range range = ...;
var slice1 = source3.ElementsIn(range); // or Slice(range)
var slice2 = source4.ElementsIn(2..^2) // or Slice(2..^2)
var slice2 = source5.ElementsIn(^10..); // or Slice(^10..)

The following Range overload and AsEnumerable overload for System.Range convert it to a sequence, so that LINQ query can be started fluently from c# range:

var query1 = Enumerable.Range(10..).Select(...);
Range range = ...;
var query1 = range.AsEnumerable().Select(...);
var query2 = (10..20).AsEnumerable().Where(...);

APIs

For LINQ to Objects:

namespace System.Linq
{
    public static partial class EnumerableExtensions
    {
        public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, Index index) { throw null; }

        public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, Index index) { throw null; }

        public static IEnumerable<TSource> ElementsIn<TSource>(this IEnumerable<TSource> source, Range range) { throw null; }

        public static IEnumerable<TSource> Range<TSource>(Range range) { throw null; }

        public static IEnumerable<TSource> AsEnumerable<TSource>(this Range source) { throw null; }
}

For remote LINQ:

namespace System.Linq
{
    public static partial class QueryableExtensions
    {
        public static TSource ElementAt<TSource>(this IQueryable<TSource> source, Index index) { throw null; }

        public static TSource ElementAtOrDefault<TSource>(this IQueryable<TSource> source, Index index) { throw null; }

        public static IQueryable<TSource> ElementsIn<TSource>(this IQueryable<TSource> source, Range range) { throw null; }
}

Implementation details (and pull request)

The API review process says PR should not be submitted before the API proposal is approved. So currently I implemented these APIs separately https://github.com/Dixin/Linq.IndexRange :

So that anyone can start to use these APIs by adding a NuGet package:

dotnet add package Linq.IndexRange

If this proposal is doable, I can submit a PR quickly.

The implementation of ElementAt(Index), ElementAtOrDefault(Index) and ElementsIn(Range) for IQueryable<T> is straightforward. They just create an expression tree. ElementAt(Index) and ElementAtOrDefault(Index) for IEnumerable<T>are straightforward as well.

Open questions

ElementsIn(Range)

Should it be called Slice? Currently I implement it as ElementsIn(Range range) to maintain the consistency with original ElementAt(int index), which could be natural for existing LINQ users.

What should we do when the range's start index and/or end index go off the boundaries of source sequence? There are 2 options:

  • Follow the behavior of range with array, and throw OverflowException/ArgumentEception/ArgumentOutOfRangeExceptionaccordingly.
  • Follow the behavior of current partitioning LINQ operators like Skip/Take/SkipLast/TakeLast, do not throw exception.

I implemented ElementsIn(Range) following the array behavior. See unit tests of ElementsIn. And I implemented Slicefollowing the LINQ behavior. See unit test of Slice.

ElementAt(Index) and Queryable

As @bartdesmet mentioned in the comments, LINQ providers may have issues when they see ElementAt having an Indexargument, etc. Should we have a new name for the operator instead of overload? For example, At(Index) and Slice(Range)?

Range

For Range(Range) and AsEnumerable(Range), the question is: what does range's start index and end index mean, when the index is from the end? For example, 10..20 can be easily converted to a sequence of 10, 11,12, ... 19, but how about ^20...^10?

The easiest way is to disallow, and throw exception.

My current implementation attempts to make it flexible. Regarding Index's Value can be from 0 to int.MaxValue, I assume a virtual "full range" 0..2147483648, and any Range instance is a slice of that "full range". So:

  • Ranges .. and 0.. and ..^0 and 0..^0 are converted to "full sequence" 0, 1, .. 2147483647
  • Range 100..^47 is converted to sequence 100, 101, .. 2147483600
  • Range ^48..^40 is converted to sequence 2147483600, 2147483601 .. 2147483607
  • Range 10..10 is converted to empty sequence

etc. See unit tests of Range(Range).

AsEnumerable

Should this be provided to bridge range to LINQ? For me, at least (10..20).AsEnumerable().Select().Where() is intuitive and natural.

15 Comments

  • LINQ | ArgumentOutOfRangeException: Index was out of range

    for (int i = 0; i < intFeatureIDs.Count; i++) {
    slots_for = slots_for.Where(s => s.featureSlotMapping.Any(fsm => fsm.featureID == intFeatureIDs[i]));
    }
    Here, intFeatureID.Count is 2. And throws below exception.

    Exception:
    Message=An exception was thrown while attempting to evaluate a LINQ query parameter expression. To show additional information call EnableSensitiveDataLogging() when overriding DbContext.OnConfiguring.

    Inner Exception 1: ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.

    If intFeatureIDs.Count == 1, there is no issue.

    Also, If I comment out the for loop, and manually run the code twice, it will work...

    slots = slots.Where(s => s.featureSlotMapping.Any(fsm => fsm.featureID == intFeatureIDs[1]));
    slots = slots.Where(s => s.featureSlotMapping.Any(fsm => fsm.featureID == intFeatureIDs[2]));
    Any comments are much appreciated.

  • great tnx for sharing

  • great i like that

  • Great tutorial! This has helped on my journey to use LINQ to iterate dictionaries. Cheers!

  • برخی از افراد به دلیل ترس از عواقب جراحی، به منظور درمان قطعی و دائمی هموروئید اقدام نمی کنند که همین امر باعث بروز عفونت، خونریزی و <a href="https://clinic-laser.ir/%D8%AF%D8%B1%D8%AF-%D9%87%D9%85%D9%88%D8%B1%D9%88%D8%A6%DB%8C%D8%AF/">درد بواسیر</a> می شود.

  • wow asp.net is a good site and i suggest it

  • موتور دمپر چیست؟ یکی از انواع موتور های الکتریکی <a href="https://bit.ly/rahsam1">موتور دمپر</a> می باشد. برای اطلاعات بیشتر از قیمت موتور دمپر ، برندها و سایر مشخصات به وب سایت رهسام سری بزنید.

    سیستم تهویه پارکینگ یکی از پر اهمیت ترین سیستم ها در تهویه بشمار می آید. برای آشنایی بیشتر با <a href="https://rahsamair.com/%d8%aa%d9%87%d9%88%db%8c%d9%87-%d9%be%d8%a7%d8%b1%da%a9%db%8c%d9%86%da%af/">تهویه پارکینگ</a> و طراحی و ساخت جت فن تهویه پارکینگ با قیمت مناسب به وبسایت رهسام سری بزنید.

    صداگیر یا سایلنسر چیست؟ برای اطلاع از لیست قیمت فروش فن <a href="https://rahsamair.com/صداگیر/">سایلنسر</a> و صداگیر به به این مطلب مراجعه کنید.

    دریچه هوا چیست؟ اگزاست فن چیست؟ یک دریچه هوا چه اهمیت هایی دارد؟ و انواع آن ها کدامند؟ قیمت فروش طراحی و ساخت یک <a href="https://rahsamair.com/%d8%af%d8%b1%db%8c%da%86%d9%87-%d9%87%d9%88%d8%a7/">دریچه هوا</a> چقدر است؟

    دمپر همانند شیر مانند است که وظیفه آن، کنترل هوای داخل دودکش، داکت و می باشد. مهمترین کار <a href="https://rahsamair.com/%d8%af%d9%85%d9%be%d8%b1/">دمپر</a> کنترل هوا می باشد. قیمت فروش انواع دمپر هوا در سایت رهسام موجود می باشد.

  • امروزه انواع آبسردکن ها در طرح ها و رنگ های مختلف ساخته می شوند، که بهترین نوع آن آبسردکن های هیتما می باشد. هیتما یک برند ایتالیایی است که با کیفیت ترین آبسرکن ها را تولید می کند. برای اطلاع از قیمت فروش آبسردکن به وب سایت نمایندگی هیتما در ایران سری بزنید.

  • یکی از بهترین پرکننده ها و پرکاربرد ترین برای درمان چین و چروک تزریق ژل و بوتاکس می باشد. کاربردها، فواید، عوارض، هزینه و تاثیر ژل و بوتاکس را در وب سایت دکتر مهدیانی بخوانید.

  • از مزایای نوسازی برای مالکین ساختمان های قدیمی چه می دانید؟ یا در قرارداد های مشارکتی چه مواردی لحاظ می شود؟ برای اطلاعات بیشتر در مورد مشارکت در ساخت به مطلبی که توسط مشاوران و مهندسان خبره شرکت ساختمانی سین گروپ نوشته شده است توجه کنید.

  • امروزه بیشتر والدین فرزندان خود را به مدرسه دو زبانه در تهران میفرستند تا با زبان دوم آشنا شوند. این مدارس مدرن و پیشرفته هستند و بهترین امکانات در این مدارس برای رفاه و پیشرفت دانش آموزان موجود می باشد. در حال حاظر دبستان دوزبانه پیشرو بهترین مدرسه دو زبانه در تهران می باشد. برای اطلاعات بیشتر از مزایا و فواید و کلیدی ترین اهداف روی لینک کلیک کنید.

  • با ورود پروفیل های upvc به دنیای درب و پنجره تحول عظیمی در این حوزه به وجود آمد که این تحولات مزیت های فراوانی را برای مصرف کنندگان این محصول به همراه داشت. در این بین می توان به پروفیل وینتک به عنوان یک تولید کننده پروفیل های upvc اشاره کرد.

  • کودکان به دلیل عدم توانایی در برابر استفاده از انواع ماسک‌ها و لوازم بهداشتی، در برابر بسیاری از ویروس‌ها و باکتری ها نا ایمن خواهند بود. راهکارهای متفاوتی برای امنیت کودکان در مواقع خطر، ارائه شده است. راهکارهایی مانند عدم بیرون آمدن از منزل و یا استفاده از شیلد صورت برای کودکان، از جمله مهمترین راهکارها برای امنیت آنها خواهد بود. در وب سایت دانا پلاست ایرانیان اطلاعات بیشتری را در مورد شیلد کودکان بخوانید.

  • با توجه به فضای گسترده کسب و کارای اینترنتی، تمام وبسایت بایستی زیر نظر یک یا چند متخصص در حوزه های مختلف باشد. هر کدام از این خدمات شامل سئو و بهینه سازی سایت، امنیت و جلوگیری از هک، طراحی وبرسی مشکلات فنی و بک آپ گیری متناوب و ... به صورت 24 ساعته می باشد. تیم حرفه ای آمینا گروپ انواع خدمات پشتیبانی و نگهداری وب سایت را با بهترین کیفیت و بیشترین بازدهی انجام می دهد. برای دریافت این خدمات با مشاوران آمینا گروپ تماس بگیرید.

  • seo به معنای (Search Engine Optimization) سئو و بهینه سازی در موتور های جستجو است. بیشتر وب سایت ها برای دریافت بازدید بیشتر به بهینه سازی و سئوی خود روی می آورند. امروزه بیشترین کاربرد سئو در به نمایش درآوردن سایت در صفحه اول گوگل است. شرکت آمینا گروپ خدمات سئو و بهینه سازی سایت را با بهترین کیفیت و در رنج گسترده ای از کلمات کلیدی برای مشتریان خود انجام می دهد.

Add a Comment

As it will appear on the website

Not displayed

Your website