C# Linq源碼分析之Take (二)

概要

本文主要分析Linq中Take帶Range參數的重載方法的源碼。

源碼分析

基于Range參數的Take重載方法,主要分成兩部分實現,一部分是Range中的開始和結束索引都是正數的情況例如取第一個到第三個元素的情況;另一部分是開始或結束索引中有倒數的情況,例如取倒數第三個到倒數第一個的情況。

本文著重分析Range中的正數情況。

public static IEnumerable<TSource> Take<TSource>(this IEnumerable<TSource> source, Range range)
{if (source == null){    ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);}Index start = range.Start;Index end = range.End;bool isStartIndexFromEnd = start.IsFromEnd;bool isEndIndexFromEnd = end.IsFromEnd;int startIndex = start.Value;int endIndex = end.Value;Debug.Assert(startIndex >= 0);Debug.Assert(endIndex >= 0);if (isStartIndexFromEnd){if (startIndex == 0 || (isEndIndexFromEnd && endIndex >= startIndex)){return Empty<TSource>();}}else if (!isEndIndexFromEnd){return startIndex >= endIndex? Empty<TSource>(): TakeRangeIterator(source, startIndex, endIndex);}return TakeRangeFromEndIterator(source, isStartIndexFromEnd, startIndex, isEndIndexFromEnd, endIndex);
}
  1. 檢查源序列是否為空,如果為空,直接拋出異常;
  2. 獲取Range的啟始和結束的索引值,以及索引值是正數還是倒數的bool值;
  3. 如果開始索引值是倒數,以下幾種情況返回空序列:
    (a)開始索引是^0, 倒數第0個,顯然不合理
    (b)Range形如 ^1… ^3的情況,假設有10個元素, ^1… ^3相當于取從第10個到第7個,顯然是不合理。應該是從第7個到第10個
    (c)Range形如 ^2 … ^2因為開始和結束索引相同,中間沒有間隔元素,該種情況也不合理
  4. 在Range中的開始和結束索引都不是倒數的情況下,如果開始索引大于結束索引,即Range形如2…1,返回空序列;否則調用TakeRangeIterator方法,完成具體取值操作;
  5. 對于合理的Range倒數情況,例如形如 ^3… ^1 , 3… ^1 或 ^3 … 10 這些情況,執行最后的TakeRangeFromEndIterator方法。

TakeRangeIterator方法

TakeRangeIterator方法用于處理Range中的開始和結束索引都是正數的情況。該方法位于Take.SizeOpt文件中。通過yield return/break的方式管理迭代過程。

private static IEnumerable<TSource> TakeRangeIterator<TSource>(IEnumerable<TSource> source, int startIndex, int endIndex)
{Debug.Assert(source != null);Debug.Assert(startIndex >= 0 && startIndex < endIndex);using IEnumerator<TSource> e = source.GetEnumerator();int index = 0;while (index < startIndex && e.MoveNext()){++index;}if (index < startIndex){yield break;}while (index < endIndex && e.MoveNext()){yield return e.Current;++index;}
}
  1. 創建迭代器e,采用using方式,在函數執行完成后,自動釋放內存空間;
  2. 如果Range中的索引數據和source序列中的元素個數不匹配,例如指定從第三個元素開始取,但是數列里面只有兩個元素,返回yield break,關閉狀態機,注意,此種情況并不會拋出越界異常;
  3. 按照索引范圍,通過迭代器e取值,創建狀態機,通過yield return方式返回。

TakeRangeFromEndIterator方法

TakeRangeIterator方法用于處理Range中的開始和結束索引存在倒數的情況。該方法位于Take.cs文件中。通過yield return/break的方式管理迭代過程。

該方法篇幅較長,將在C# Linq源碼分析之Take (三)中詳細分析其源碼。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41924.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41924.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41924.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

華為AI戰略的CANN

基于TVM的華為昇騰體系中—— 異構計算架構&#xff08;CANN&#xff09;是對標英偉達的CUDA CuDNN的核心軟件層&#xff0c;向上支持多種AI框架&#xff0c;向下服務AI處理器&#xff0c;發揮承上啟下的關鍵作用&#xff0c;是提升昇騰AI處理器計算效率的關鍵平臺 主要包括有…

ES安裝問題匯總

max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535] 問題描述 ES啟動報錯。其原因是ES需要的的最小max file descriptors為65535&#xff0c;我們設置的是4096&#xff0c;需要增大max file descriptors的值。 解決方案 調大…

“new出對象“原理的深層解密

&#x1f388;個人主頁:&#x1f388; :???初階牛??? &#x1f43b;推薦專欄1: &#x1f354;&#x1f35f;&#x1f32f;C語言初階 &#x1f43b;推薦專欄2: &#x1f354;&#x1f35f;&#x1f32f;C語言進階 &#x1f511;個人信條: &#x1f335;知行合一 &#x1f…

正規的股票杠桿公司_杠桿公司排名(2023年版的)

本文將介紹一些正規的股票杠桿公司&#xff0c;并重點介紹配先查網站的特點&#xff0c;該網站是一家專業查詢實盤杠桿平臺的網站&#xff0c;提供相關信息和參考。 杠桿公司排名&#xff08;2023年版的&#xff09;&#xff1a;廣盛網、一鼎盈、尚紅網、盛多網、紅騰網、富燈…

Oracle/PL/SQL奇技淫巧之ROWNUM偽列

ROWNUM偽列 ROWNUM是一個偽列&#xff0c;它是根據每次查詢的結果動態生成的一列遞增編號&#xff0c;表示 Oracle 從表中選擇該行的順序&#xff0c;選擇的第一行ROWNUM為1&#xff0c;第二行ROWNUM為2&#xff0c;以此類推。 注意1&#xff1a; ROWNUM偽列是在WHERE子句之…

Mybatis——返回值(resultType&resultMap)詳解

之前的文章里面有對resultType和resultMap的簡單介紹這一期出點詳細的 resultType&#xff1a; 1&#xff0c;返回值為簡單類型。 直接使用resultType“類型”&#xff0c;如string&#xff0c;Integer等。 String getEmpNameById(Integer id); <!-- 指定 result…

Linux內核源碼剖析之TCP保活機制(KeepAlive)

寫在前面&#xff1a; 版本信息&#xff1a; Linux內核2.6.24&#xff08;大部分centos、ubuntu應該都在3.1。但是2.6的版本比較穩定&#xff0c;后續版本本質變化也不是很大&#xff09; ipv4 協議 https://blog.csdn.net/ComplexMaze/article/details/124201088 本文使用案例…

高級AI賦能Fortinet FortiXDR解決方案

擴展檢測和響應 (XDR&#xff1a;Extended Detection and Response) 解決方案旨在幫助組織整合分布式安全技術&#xff0c;更有效地識別和響應活動的威脅。雖然 XDR 是一種新的技術概念&#xff0c;但其構建基礎是端點檢測和響應 (EDR&#xff1a;Endpoint Detection and Respo…

代碼隨想錄算法訓練營第50天|動態規劃part11

8.16周三 123.買賣股票的最佳時機III 188.買賣股票的最佳時機IV 詳細布置 123.買賣股票的最佳時機III 題目&#xff1a;最多買賣兩次 題解&#xff1a; 1、 dp[i][0]沒有操作 &#xff08;其實我們也可以不設置這個狀態&#xff09; dp[i][1]第一次持有股票 dp[i][2]第一…

CSDN?索尼 toio?應用創意開發征集征集活動 創意公示! 入選的用戶看過來~

索尼toio?應用創意開發征集活動自開啟以來&#xff0c;收到了很多精彩的創意&#xff01;接下來&#xff0c;我們將公示入選的20個優秀創意和10個入圍創意&#xff0c;以下提到ID的小伙伴注意啦&#xff0c;你們將有機會順利進入活動的第二階段&#xff0c;注意查收你們的信箱…

javaScript:快樂學習計時器

目錄 一.前言 二.計時器 1.計時器的分類 2. 創建計時器的方式 創建間隔計時器 創建方式三種 1.匿名函數 2.使用函數直接作為計時器的執行函數 2.使用函數直接作為計時器的執行函數,用字符串的形式寫入 3.計時器的返回值 4.清除計時器 5.延遲計時器 相關代碼 一.前言 在…

Linux--實用指令與方法(部分)

下文主要是一些工作中零碎的常用指令與方法 實用指令與方法&#xff08;部分&#xff09; linux長時間保持ssh連接 這個問題的原因是&#xff1a;設置檢測時間太短&#xff0c;或者沒有保持tcp長連接。 解決步驟&#xff1a; 步驟1&#xff1a;打開sshd配置文件&#xff0…

nbcio-boot從3.0升級到3.1的出現用戶管理與數據字典bug

升級后出現 系統管理里的用戶管理出現下面問題 2023-08-17 09:44:38.902 [http-nio-8080-exec-4] [1;31mERROR[0;39m [36mo.jeecg.common.exception.JeecgBootExceptionHandler:69[0;39m - java.lang.String cannot be cast to java.lang.Long java.lang.ClassCastException:…

【JS 線性代數算法之向量與矩陣】

線性代數算法 一、向量的加減乘除1. 向量加法2. 向量減法3. 向量數乘4. 向量點積5. 向量叉積 二、矩陣的加減乘除1. 矩陣加法2. 矩陣減法3. 矩陣數乘4. 矩陣乘法 常用數學庫 線性代數是數學的一個分支&#xff0c;用于研究線性方程組及其解的性質、向量空間及其變換的性質等。在…

windows bat腳本,使用命令行增加/刪除防火墻:入站-出站,規則

常常手動設置防火墻的入站或出站規則&#xff0c;比較麻煩&#xff0c;其實可以用命令行搞定。 下面是禁用BCompare.exe連接網絡的例子&#xff1a; ECHO OFF&(PUSHD "%~DP0")&(REG QUERY "HKU\S-1-5-19">NUL 2>&1)||(powershell -Comm…

web即時通訊系統與APP即時通訊系統有什么區別?

隨著互聯網的不斷發展&#xff0c;即時通訊技術也在不斷地完善和發展&#xff0c;其中Web即時通訊系統和APP即時通訊系統成為了人們廣泛使用的兩種通訊方式。那么&#xff0c;這兩者之間究竟有什么區別呢&#xff1f;在本文中&#xff0c;我們將為您詳細介紹這兩種通訊方式的區…

如何將labelImg打包成exe

最近整理一下數據標注這塊的內容&#xff0c;在目標檢測和目標分割里面用的最多的標注工具labelimg&#xff0c;labelme labelimg主要用于目標檢測領域制作自己的數據集&#xff0c;如&#xff1a;YOLO系列目標檢測模型 labelme主要用于圖像分割領域制作自己的數據集&#xf…

如何仿寫簡易tomcat 實現思路+代碼詳細講解

仿寫之前&#xff0c;我們要搞清楚都要用到哪些技術 自定義注解&#xff0c;比如Tomcat使用的是Servlet&#xff0c;我們可以定義一個自己的MyServlet構造請求體和返回體&#xff0c;比如tomcat使用HttpRequest&#xff0c;我們可以自己定義myHttpRequestjava去遍歷一個指定目…

Structs新增接口 報錯404,找不到資源

起因&#xff1a;最近在一個古老框架structs上開發新功能&#xff0c;由于之前沒接觸過&#xff0c;故此記錄 新增接口&#xff0c; 接口類&#xff1a; Path("/A") Produces({ MediaType.APPLICATION_JSON }) public interface Money {POSTPath("/B")Resu…

數據結構——鏈表詳解

鏈表 文章目錄 鏈表前言認識鏈表單鏈表結構圖帶頭單循環鏈表結構圖雙向循環鏈表結構圖帶頭雙向循環鏈表結構圖 鏈表特點 鏈表實現(帶頭雙向循環鏈表實現)鏈表結構體(1) 新建頭節點(2) 建立新節點(3)尾部插入節點(4)刪除節點(5)頭部插入節點(6) 頭刪節點(7) 尋找節點(8) pos位置…