You are on page 1of 88

‫ﺩﺭﺑﺎﺭﻩ ﻧﻮﻳﺴﻨﺪﻩ‬

‫ﻋﻠﻲ ﺍﻗﺪﻡ ﺍﺯ ﺍﺑﺘﺪﺍ ﻱ ﺁﺷﻨﺎﻳﻲ ﺧﻮﺩ ﺑﺎ ﮐﺎﻣﭙﻴﻮﺗﺮ ﻋﻼﻗﻪ ﻱ ﻋﺠﻴﺒﻲ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻭ ﻃﺮﺍﺣﻲ‬
‫ﺣﺲ ﮐﺮﺩ ﻭ ﺗﻤﺎﻡ ﺗﻼﺵ ﺧﻮﺩ ﺭﺍ ﺩﺭ ﺍﻳﻦ ﺯﻣﻴﻨﻪ ﻫﺎ ﺍﻧﺠﺎﻡ ﺩﺍﺩ‪ ،‬ﺩﺭ ﺳﺎﻝ‪ 88‬ﺑﻪ ﺩﻧﻴﺎﻱ ‪.NET‬‬
‫ﻭﺍﺭﺩ ﺷﺪ ﻭ ﺳﻌﻲ ﮐﺮﺩ ﺗﺎ ﻣﻔﺎﻫﻴﻢ ﻣﺮﺑﻮﻁ ﺑﻪ ﺍﻳﻦ ﭘﻠﺘﻔﺮﻡ ﺭﺍ ﻓﺮﺍ ﺑﮕﻴﺮﺩ‪.‬‬

‫ﺍﻭ ﻫﻢ ﺍﮐﻨﻮﻥ ﺩﺭ ﺣﺎﻝ ﺗﺤﺼﻴﻞ ﺩﺭ ﺭﺷﺘﻪ ﻣﻬﻨﺪﺳﻲ ﻧﺮﻡ ﺍﻓﺰﺍﺭ ﻭ ﺩﺭ ﺣﺎﻝ ﺁﻣﺎﺩﻩ ﺷﺪﻥ ﺑﺮﺍﻱ‬
‫ﺁﺯﻣﻮﻥ ﻫﺎﻱ ‪ MCTS‬ﺍﺳﺖ‪ .‬ﺍﻳﻦ ﺍﺛﺮ ﺣﺎﺻﻞ ﻣﻄﺎﻟﻌﺎﺕ ﺍﻭ ﺩﺭ ﺯﻣﻴﻨﻪ ‪ LINQ‬ﺍﺳﺖ ﻭ ﺍﺯ ﺁﻧﺠﺎﻱ‬
‫ﮐﻪ ﻫﻴﭻ ﺍﺛﺮﻱ ﺑﺪﻭﻥ ﺍﺷﻐﺎﻝ ﻧﻤﻲ ﺑﺎﺷﺪ‪ ،‬ﺧﻮﺷﺤﺎﻝ ﺧﻮﺍﻫﺶ ﺷﺪ ﮐﻪ ﺍﺷﮑﺎﻻﺕ ﻭ ﭘﻴﺸﻨﻬﺎﺩﺍﺕ ﺧﻮﺩ ﺭﺍ ﺑﺎ ﺍﻭ ﺩﺭ ﻣﻴﺎﻥ ﺑﮕﺬﺍﺭﻳﺪ‪.‬‬

‫ﺑﺮﺍﻱ ﺁﺷﻨﺎﻳﻲ ﺑﻴﺸﺘﺮ ﺑﺎ ﺍﻭ ﻧﻮﺷﺘﻪ ﻫﺎﻱ ﺍﻭ ﻣﻲ ﺗﻮﺍﻥ ﺑﻪ ﻭﺑﻼﮒ ﺍﻭ ﻣﺮﺍﺟﻌﻪ ﮐﻨﻴﺪ‪ ،‬ﻫﻤﭽﻨﻴﻦ ﻣﻲ ﺗﻮﺍﻧﻴﺪ ﺑﺎ ﺭﺍﻳﺎﻧﺎﻣﻪ ﻫﺎﻱ ﺯﻳﺮ ﺑﺎ ﺍﻭ‬
‫ﺍﺭﺗﺒﺎﻁ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ‪.‬‬

‫‪www.aliaghdam.ir‬‬
‫‪U‬‬ ‫‪U‬‬

‫‪info@aliaghdam.ir‬‬
‫‪U‬‬ ‫‪U‬‬

‫‪alitopack@gmail.com‬‬
‫‪U‬‬ ‫‪U‬‬
‫ﻓﻬﺮﺳﺖ ﻣﻄﺎﻟﺐ‬

‫ﻓﺼﻞ ﺍﻭﻝ ‪ -‬ﻣﻘﺪﻣﻪ ﺍﻱ ﺑﺮ ‪LINQ‬‬

‫‪........................................................................................................................................................................................................‬‬
‫‪1‬‬ ‫ﻣﻘﺪﻣﻪ ﻓﺼﻞ‬

‫‪ LINQ‬ﭼﻴﺴﺖ؟ ‪..................................................................................................................................................................................................‬‬
‫‪2‬‬

‫ﺍﺳﻤﺒﻠﻲ ﻫﺎﻱ ﻣﺮ ﮐﺰﻱ ‪2......................................................................................................................................................................... LINQ‬‬

‫ﻧﻮﺷﺘﻦ ﺍﻭﻟﻴﻦ ﺑﺮﻧﺎﻣﻪ ﺗﻮﺳﻂ ‪3.................................................................................................................................................................... LINQ‬‬

‫ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫ﻣﻘﺪﻣﻪ ﻓﺼﻞ ‪5 ...................................................................................................................................................................................................‬‬

‫ﻧﻮﻉ ﻫﺎﻱ ﺑﻲ ﻧﺎﻡ ‪5 ................................................................................................................................................ Anonymous types -‬‬

‫ﻣﻘﺪﺍﺭ ﺩﻫﻨﺪﻩ ﺍﻭﻟﻴﻪ ﺑﻪ ﺍﺷﻴﺎﺀ ‪6.................................................................................................................................... Object Initializers -‬‬

‫ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ ‪7....................................................................................................................................................... Type Inference -‬‬

‫ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ‪9..................................................................................................................................................... Extension Methods -‬‬

‫‪10‬‬
‫ﺗﻌﺮﻳﻒ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ‪.....................................................................................................................................................................................‬‬

‫‪10‬‬
‫ﻓﺮﺍﺧﻮﺍﻧﻲ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺩﺭ ﺳﻄﺢ ﻧﻤﻮﻧﻪ ﺍﻱ ‪...................................................................................................................................................‬‬

‫‪11‬‬
‫ﻓﺮﺍﺧﻮﺍﻧﻲ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺩﺭ ﺳﻄﺢ ﺍﻳﺴﺘﺎ ‪.........................................................................................................................................................‬‬

‫ﺍﺳﺘﻔﺎﺩﻩ ‪ Intelisense‬ﺍﺯ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ‪....................................................................................................................................................‬‬


‫‪11‬‬

‫‪12‬‬
‫ﺗﻮﺳﻌﻪ ﺭﺍﺑﻂ ﻫﺎ ﺑﻮﺳﻴﻠﻪ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ‪.............................................................................................................................................................‬‬

‫ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ‪14............................................................................................................................................. Lambda Expressions -‬‬

‫‪14‬‬
‫ﺗﻌﺮﻳﻒ ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ‪.................................................................................................................................................................................‬‬

‫ﻋﺒﺎﺭﺍﺕ ﭘﺮﺱ ﻭ ﺟﻮ ‪16................................................................................................................. ................ Query Expresions -‬‬


‫ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

21
..................................................................................................................................................................................................... ‫ﻣﻘﺪﻣﻪ ﻓﺼﻞ‬

21
............................................................................................................................................................ . ‫ﺍﻧﻮﺍﻉ ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭﺟﻮ‬

24.................................................................................................................................... Restriction Operator - ‫ﻋﻤﻠﮕﺮ ﺷﺮﻃﻲ‬

24....................................................................................................................................................................................... Where ‫ﻋﻤﻠﮕﺮ‬

25...................................................................................................................................................................................... OfType ‫ﻋﻤﻠﮕﺮ‬

27.................................................................................................................................... Projection Oprators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﭘﺮﺗﻮ‬

27......................................................................................................................................................................................... Select ‫ﻋﻤﻠﮕﺮ‬

28........................................................................................................................................................................... SelectMany ‫ﻋﻤﻠﮕﺮ‬

30................................................................................................................................................. Join Operators ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺗﺼﺎﻝ‬

30.............................................................................................................................................................................................. Join ‫ﻋﻤﻠﮕﺮ‬

32............................................................................................................................................................................... GroupJoin ‫ﻋﻤﻠﮕﺮ‬

33...................................................................................................................... Grouping Operators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺩﺳﺘﻪ ﺑﻨﺪﻱ‬

33................................................................................................................................................................................. Group By ‫ﻋﻤﻠﮕﺮ‬

35.................................................................................................................... Ordering Operators - ‫ﻋﻤﻠﮕﺮ ﻫﺎﻱ ﻣﺮﺗﺐ ﺳﺎﺯﻱ‬

35................................................................................................................................................................................... OrderBy ‫ﻋﻤﻠﮕﺮ‬

36...................................................................................................................................................... descending OrderBy ‫ﻋﻤﻠﮕﺮ‬

37......................................................................................................................................................................................Thenby ‫ﻋﻤﻠﮕﺮ‬

38............................................................................................................................................................ThenByDecending ‫ﻋﻤﻠﮕﺮ‬

39....................................................................................................................................................................................Reverse ‫ﻋﻤﻠﮕﺮ‬

40......................................................................................................................... Agreagate Operators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﺠﻤﻌﻲ‬

40...................................................................................................................................................................................... Count ‫ﻋﻤﻠﮕﺮ‬

41........................................................................................................................................................................... LongCount ‫ﻋﻤﻠﮕﺮ‬


41............................................................................................................................................................................................. Sum ‫ﻋﻤﻠﮕﺮ‬

42............................................................................................................................................................................... Max ‫ ﻭ‬Min ‫ﻋﻤﻠﮕﺮ‬

44.................................................................................................................................................................................... Average ‫ﻋﻤﻠﮕﺮ‬

45................................................................................................................................................................................Aggregate ‫ﻋﻤﻠﮕﺮ‬

46............................................................................................................. Partitioning Operators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﻗﺴﻤﺖ ﺑﻨﺪﻱ‬

46............................................................................................................................................................................................ Take ‫ﻋﻤﻠﮕﺮ‬

47............................................................................................................................................................................................. Skip ‫ﻋﻤﻠﮕﺮ‬

47.............................................................................................................................................................................. TakeWhile ‫ﻋﻤﻠﮕﺮ‬

48................................................................................................................................................................................ SkipWhile ‫ﻋﻤﻠﮕﺮ‬

50................................................................................................................................. Concatation Operator - ‫ﻋﻤﻠﮕﺮ ﺍﻟﺤﺎﻗﻲ‬

50............................................................................................................................................................................................. Concat ‫ﻋﻤﻠﮕﺮ‬

50............................................................................................................................. Element Operators - ‫ﻋﻤﻠﮕﺮ ﻫﺎﻱ ﻋﻨﺼﺮﻱ‬

50............................................................................................................................................................................................... ... First ‫ﻋﻤﻠﮕﺮ‬

51........................................................................................................................................................................... FirstOrDefault ‫ﻋﻤﻠﮕﺮ‬

52.................................................................................................................................................................................................... Last ‫ﻋﻤﻠﮕﺮ‬

53............................................................................................................................................................................ LastOrDefault ‫ﻋﻤﻠﮕﺮ‬

54............................................................................................................................................................................................... Single ‫ﻋﻤﻠﮕﺮ‬

55........................................................................................................................................................................ SingleOrDefault ‫ﻋﻤﻠﮕﺮ‬

56.................................................................................................................................................................................... ElementAt ‫ﻋﻤﻠﮕﺮ‬

57............................................................................................................................................................ ElementAtOrDefault ‫ﻋﻤﻠﮕﺮ‬

58............................................................................................................................................................................ DefaultEmpty ‫ﻋﻤﻠﮕﺮ‬

59......................................................................................................................... Generation Operators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﻮﻟﻴﺪﻱ‬

59....................................................................................................................................................................................... Repeat ‫ﻋﻤﻠﮕﺮ‬


60......................................................................................................................................................................................... Range ‫ﻋﻤﻠﮕﺮ‬

61........................................................................................................................................................................................ Empty ‫ﻋﻤﻠﮕﺮ‬

62................................................................................................................................... Set Operators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﻨﻄﻴﻢ ﮐﻨﻨﺪﻩ‬

62.................................................................................................................................................................................... Distinct ‫ﻋﻤﻠﮕﺮ‬

63................................................................................................................................................................................. Intersect ‫ﻋﻤﻠﮕﺮ‬

64........................................................................................................................................................................................ Union ‫ﻋﻤﻠﮕﺮ‬

65....................................................................................................................................................................................... Except ‫ﻋﻤﻠﮕﺮ‬

67................................................................................................................................................................................................ Zip ‫ﻋﻤﻠﮕﺮ‬

68................................................................................................................. Quantifier Operators - ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﮐﻤﻴﺖ ﺳﻨﺞ‬

68................................................................................................................................................................................................. All ‫ﻋﻤﻠﮕﺮ‬

69.............................................................................................................................................................................................. Any ‫ﻋﻤﻠﮕﺮ‬

70.................................................................................................................................................................................. Contains ‫ﻋﻤﻠﮕﺮ‬

71............................................................................................................................ Conversion Operators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﺒﺪﻳﻞ‬

71............................................................................................................................................................................................. Cast ‫ﻋﻤﻠﮕﺮ‬

72.................................................................................................................................................................................... ToArray ‫ﻋﻤﻠﮕﺮ‬

73......................................................................................................................................................................................... ToList ‫ﻋﻤﻠﮕﺮ‬

74........................................................................................................................................................................ ToDictionary ‫ﻋﻤﻠﮕﺮ‬

75............................................................................................................................................................................... ToLookup ‫ﻋﻤﻠﮕﺮ‬

76.................................................................................................................................................................... AsEnumerable ‫ﻋﻤﻠﮕﺮ‬


‫ﻣﻘﺪﻣﻪ ﺍﻱ ﺑﺮ ‪LINQ‬‬

‫‪1‬‬ ‫ﺍﻣﺮﻭﺯﻩ ﺑﺎ ﻭﺟﻮﺩ ﺯﺑﺎﻥ ﻫﺎﻱ ﺷﻲ ﮔﺮﺍ ﮐﻪ ﻗﺎﺑﻠﻴﺖ ﻫﺎﻱ ﺭﺍ ﺩﺭ ﺍﺧﺘﻴﺎﺭ ﺗﻮﺳﻌﻪ ﺩﻫﻨﺪﮔﺎﻥ ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ‪ ،‬ﺭﻭﺵ ﻫﺎﻱ‬
‫ﻣﺨﺘﻠﻔﻲ ﺑﺮﺍﻱ ﺍﺭﺗﺒﺎﻁ ﺑﺎ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻫﺎﻱ ﺭﺍﺑﻄﻪ ﺍﻱ ﻭﺟﻮﺩ ﺩﺍﺭﺩ ﮐﻪ ﻓﻘﺪﺍﻥ ﺭﻭﺷﻲ ﻣﺸﺨﺺ ﻭ ﺁﺳﺎﻥ ﺑﺮﺍﻱ ﺍﺗﺼﺎﻝ‬
‫ﺑﻪ ﺍﻧﻮﺍﻉ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻫﺎﻱ ﺭﺍﺑﻄﻪ ﺍﻱ ﻭ ﺑﻪ ﺻﻮﺭﺕ ﮐﻠﻲ ﺑﻪ ﻫﺮ ﻧﻮﻉ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺍﻱ ﮐﻪ ﺑﻪ ﺻﻮﺭﺕ ﺷﺊ ﻧﻴﺴﺖ‪،‬‬
‫ﺍﺣﺴﺎﺱ ﻣﻲ ﺷﻮﺩ‪.‬‬

‫ﺷﺎﻳﺪ ﺷﻤﺎ ﺑﮕﻮﻳﻴﺪ ﮐﻪ ‪ ADO.NET‬ﻣﻲ ﺗﻮﺍﻧﺪ ﺑﺎ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻣﻔﻬﻮﻡ ‪ DataSet‬ﺑﻪ ﺍﻳﻦ ﺁﺭﻣﺎﻥ ﺩﺳﺖ ﻳﺎﻓﺖ ﺍﻣﺎ ﺑﺮﺍﻱ ﺗﺤﻘﻖ ﺁﻥ‬
‫ﻣﻲ ﺑﺎﻳﺴﺖ ﺍﺯ ﻳﮏ ﺷﻲ ‪ DataAdapter‬ﺍﺳﺘﻔﺎﺩﻩ ﮎﺭﺩ‪ .‬ﻳﮏ ﺷﻲ ‪ DataAdapter‬ﭼﻬﺎﺭ ﺷﻲ ‪ Command‬ﺭﺍ ﺩﺭ ﺧﻮﺩ ﭘﻴﺎﺩﻩ‬
‫ﺳﺎﺯﻱ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﺍﻳﻦ ﺍﺷﻲﺍﺀ ﺑﺮﺍﻱ ﺍﻧﺠﺎﻡ ﻋﻤﻠﻴﺎﺕ ‪ Update ¡ Delete ¡ Select‬ﻭ ‪ Insert‬ﺑﺮ ﺭﻭﻱ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻣﻮﺭﺩ‬
‫‪SQL‬‬ ‫ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﻧﺪ ﻭﻟﻲ ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﮐﻪ ﺑﺮﺍﻱ ﺍﻧﺠﺎﻡ ﺍﻳﻦ ﻋﻤﻞ ﺷﻤﺎ ﻣﻲ ﺑﺎﻳﺴﺖ ﺍﻳﻦ ﺍﺷﻴﺎﺀ ﺭﺍ ﺑﺎ ﻋﺒﺎﺭﺕ‬
‫‪SQL‬‬ ‫ﻣﻨﺎﺳﺐ ﺧﻮﺩ ﻣﻘﺪﺍﺭ ﺩﻫﻲ ﮐﻨﻴﺪ ﻭ ﮐﻪ ﺑﺮﺍﻱ ﺑﺎ ﺍﻧﺠﺎﻡ ﺍﻳﻦ ﻋﻤﻞ ﺗﺎ ﻫﻨﮕﺎﻡ ﺍﺟﺮﺍﻱ ﺑﺮﻧﺎﻣﻪ ﻧﻤﻲ ﺗﻮﺍﻧﻴﻢ ﺍﺯ ﺻﺤﺖ ﻋﺒﺎﺭﺕ‬
‫ﺧﻮﺩ ﺍﻃﻤﻴﻨﺎﻥ ﮐﺴﺐ ﮐﻨﻴﺪ‪ .‬ﺍﻳﻦ ﺑﺪﺍﻥ ﻣﻌﻨﺎﺳﺖ ﮐﻪ ﻋﺒﺎﺭﺍﺕ ‪ SQL‬ﺩﺭ ﺯﺑﺎﻥ ﻫﺎﻱ ﺩﺍﺕ ﻧﺖ ﺑﻴﮕﺎﻧﻪ ﻫﺴﺘﻨﺪ ﻭ ﻋﺒﺎﺭﺕ ‪ SQL‬ﻣﻘﺪﺍﺭ‬
‫ﺩﻫﻲ ﺷﺪﻩ ﺑﺮﺍﻱ ﺩﺍﺕ ﻧﺖ ﻭ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺩﺭ ﺗﺎﺭﻳﮑﻲ ﺍﺳﺖ ! ﻭ ﺗﺎ ﺍﺟﺮﺍ ﻧﺸﺪﻥ ﻋﺒﺎﺭﺕ ‪ SQL‬ﺍﺯ ﺻﺤﺖ ﻋﺒﺎﺭﺕ ﻫﻴﭻ ﺍﻃﻼﻋﻲ‬
‫ﻧﺪﺍﺭﻳﻢ‪.‬‬
‫|ﺻﻔﺤﻪ‪2‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫‪ LINQ‬ﭼﻴﺴﺖ؟‬

‫ﺩﺭ ﮐﻨﻔﺮﺍﻧﺲ ﺗﻮﺳﻌﻪ ﺩﻫﻨﺪﮔﺎﻥ ﺣﺮﻓﻪ ﺍﻱ ﻣﺎﻳﮑﺮﻭﺳﺎﻓﺖ ‪ ϭ‬ﺩﺭ ﺳﺎﻝ‪ ، 2005‬ﺁﻗﺎﻱ ﻫﻠﺴﺒﺮﮒ ‪ Ϯ‬ﻳﮏ ﺗﮑﻨﻮﻟﻮﮊﻱ ﺟﺪﻳﺪ ﮐﻪ‬
‫ﺑﺘﻮﺍﻥ ﺑﻪ ﻭﺳﻴﻠﻪ ﺁﻥ ﺑﺎ ﻫﺮ ﻧﻮﻉ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺍﻱ ﺑﻪ ﻳﮏ ﺭﻭﺵ ﻳﮑﺴﺎﻥ ﺍﺗﺼﺎﻝ ﺑﺮﻗﺮﺍﺭ ﮐﺮﺩ ‪ ،‬ﺑﻪ ﻧﺎﻡ ‪ LINQ‬ﻣﻌﺮﻓﻲ ﻧﻤﻮﺩ‪.‬‬

‫‪ LINQ‬ﻣﺨﻔﻒ ﻋﺒﺎﺭﺕ ‪ Language-Integrated Query‬ﺍﺳﺖ ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﮐﻪ ﺁﻥ ﺭﺍ ﻟﻴﻨﮏ )‪ (Link‬ﺗﻠﻔﻆ ﮐﻨﻴﺪ‪.‬‬

‫‪ LINQ‬ﻳﮏ ﺭﺍﻩ ﺣﻞ ﻳﮑﺴﺎﻥ ﺑﺮﺍﻱ ﺍﺗﺼﺎﻝ ﺑﺮﻗﺮﺍﺭ ﮐﺮﺩﻥ ﻭ ﺑﺎﺯﻳﺎﺑﻲ ﺍﻃﻼﻋﺎﺕ ﺍﺯ ﻫﺮ ﺷﻲ ﮐﻪ ﺭﺍﺑﻂ ‪ IEnumerable‬ﺭﺍ ﭘﻴﺎﺩﻩ‬
‫ﺳﺎﺯﻱ ﮐﺮﺩﻩ ﺑﺎﺷﺪ ﻓﺮﺍﻫﻢ ﻣﻴﮑﻨﺪ‪ .‬ﺑﻮﺳﻴﻠﻪ ‪ LINQ‬ﻣﻲ ﺗﻮﺍﻥ ﺑﺎ ﺁﺭﺍﻳﻪ ﻫﺎ ﻭﻣﺠﻤﻮﻋﻪ ﻫﺎﻱ ‪ ϯ‬ﺩﺭﻭﻥ ﺣﺎﻓﻈﻪ ‪ ،‬ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻫﺎﻱ‬
‫ﺭﺍﺑﻄﻪ ﺍﻱ ﻭ ﺣﺘﻲ ﺍﺳﻨﺎﺩ ‪ XML‬ﺭﺍ ﺑﻪ ﻋﻨﻮﺍﻥ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺖ ﻭ ﺑﺎ ﺁﻥ ﮐﺎﺭ ﮐﺮﺩ!‬

‫ﺑﻮﺳﻴﻠﻪ ‪ LINQ‬ﻣﻲ ﺗﻮﺍﻥ ﺍﻃﻼﻋﺎﺕ ﺭﺍ ﺍﺯ ﻫﺮ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺍﻱ ﺑﺎ ﮔﺮﺍﻣﺮﻱ ﻣﺸﺎﺑﻪ ﻭ ﺧﻮﺵ ﺷﮑﻞ ﺑﺎﺯﻳﺎﺑﻲ ﮐﺮﺩ‪.‬ﮔﺮﺍﻣﺮﻱ ﮐﻪ‬
‫ﺑﺴﻴﺎﺭ ﺷﺒﻴﻪ ﺑﻪ ﻧﻮﺷﺘﺎﺭ ﻧﺤﻮﻱ ‪ SQL‬ﺍﺳﺖ‪ ،‬ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﮐﻪ ﻫﺪﻑ ﺗﻴﻢ ﺳﺎﺯﻧﺪﻩ ‪ ،LINQ‬ﺍﺿﺎﻓﻪ ﮐﺮﺩﻥ ﻳﮏ ﺭﺍﻩ ﺟﺪﻳﺪ ﺑﺮﺍﻱ‬
‫ﺑﺎﺯﻳﺎﺑﻲ ﺩﺍﺩﻫﺎ ﻧﻴﺴﺖ‪ ،‬ﺑﻠﮑﻪ ﻓﺮﺍﻫﻢ ﮐﺮﺩﻥ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺩﺳﺘﻮﺭﺍﺕ ﻣﺤﻠﻲ ﻭ ﺟﺎﻣﻊ ﺑﺮﺍﻱ ﺑﺎﺯﻳﺎﺑﻲ ﺍﻃﻼﻋﺎﺕ ‪ ϰ‬ﮐﻪ ﺍﺯ ﻫﺮ ﻧﻮﻉ‬
‫ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺍﻱ ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﮐﻦ ﮐﻪ ﺑﻮﺳﻴﻠﻪ ﺁﻧﻬﺎ ﻣﻲ ﺗﻮﺍﻥ ﭘﺮﺱ ﻭ ﺟﻮﻫﺎﻱ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩ‬‫‪ LINQ‬ﻳﻪ ﺳﺮﻱ ﻣﺠﻤﻮﻋﻪ ﺩﺳﺘﻮﺭﺍﺕ ﺗﻮﺍﻧﻤﻨﺪ ﺭﺍ ﺍﺭﺍﺋﻪ ﻣﻲ ﺩ‬
‫ﮐﻪ ﺍﺯ ﻣﻮﺍﺭﺩﻱ ﭼﻮﻥ ‪ Join‬ﻫﺎ‪ ،‬ﺗﻮﺍﺑﻊ ‪، Aggregation‬ﻣﺮﺗﺐ ﺳﺎﺯﻱ ‪ ،‬ﻓﻴﻠﺘﺮ ﻭ‪ ...‬ﭘﺸﺘﻴﺒﺎﻧﻲ ﮐﻨﺪ‪.‬ﺍﻳﻦ ﺩﺳﺘﻮﺭﺍﺕ ﺭﺍ ‪language-‬‬
‫‪ level‬ﻣﻲ ﻧﺎﻣﻨﺪ ﻭ ﺩﻳﮕﺮ ﻧﻴﺎﺯﻱ ﺑﻪ ﮐﺎﻣﭙﺎﻳﻞ ﺑﺮﺍﻱ ﺩﻳﺪﻥ ﻧﺘﻴﺠﻪ ﻧﻴﺴﺖ! ﺑﻠﻪ ﺍﻳﻦ ﻣﺸﮑﻠﻲ ﺑﻮﺩ ﮐﻪ ﺩﺭ ﺗﮑﻨﻮﻟﻮﮊﻱ ‪ ADO.NET‬ﺑﺎ‬
‫ﺁﻥ ﺩﺳﺖ ﻭ ﭘﻨﺠﻪ ﻧﺮﻡ ﻣﻲ ﮐﺮﺩﻳﻢ ‪،‬ﻳﻌﻨﻲ ﺑﺮﺍﻱ ﻣﺸﺎﻫﺪﻩ ﻧﺘﻴﺠﻪ ﮐﻮﺋﺮﻱ ﺁﻥ ﺭﺍ ﺍﺟﺮﺍ ﻣﻲ ﮐﺮﺩﻳﻢ ﮐﻪ ﻣﺸﮑﻼﺗﻲ ﺍﺯ ﻗﺒﻴﻞ ﺧﻄﺎﻳﺎﺑﻲ‬
‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺭﺍ ﺩﺷﻮﺍﺭ ﻣﻲ ﮐﺮﺩ ﻭ ﻋﺮﺻﻪ ﺗﻮﺳﻌﻪ ﺭﺍ ﺑﺴﻴﺎﺭ ﻃﻮﻻﻧﻲ ﺗﺮ‪.‬‬

‫ﺷﺎﻳﺪ ﺷﻤﺎ ﻓﮑﺮ ﮐﻨﻴﺪﮐﻪ ‪ LINQ‬ﺍﺑﺰﺍﺭﻱ ﺍﺳﺖ ﮐﻪ ﺑﺘﻮﺍﻥ ﺑﺎ ﺁﻥ ﮐﻮﺋﺮﻱ ﻫﺎﻱ ﺑﺮ ﺭﻭﻱ ﺁﺭﺍﻳﻪ ﻭ ﻣﺠﻤﻮﻋﻪ ﻫﺎ‪ ،‬ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻭ‬
‫ﻳﺎ ‪ XML‬ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩ ﻭﻟﻲ ﺍﻳﻦ ﺗﻌﺮﻳﻒ ﺩﺭﺳﺘﻲ ﺍﺯ ‪ LINQ‬ﻧﻴﺴﺖ ﺑﻠﮑﻪ ﻳﮏ ﺗﮑﻨﻮﻟﻮﮊﻱ ﺍﺳﺖ ﮐﻪ ﺑﺘﻮﺍﻥ ‪ Provider‬ﻫﺎﻱ ﺭﺍ‬
‫ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩ ﺗﺎ ﺑﻮﺳﻴﻠﻪ ﺁﻥ ﺑﺎ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻫﺎ ﺍﺭﺗﺒﺎﻁ ﺑﺮﻗﺮﺍﺭ ﮐﺮﺩ ﺑﻪ ﻃﻮﺭ ﻣﺜﺎﻝ ‪ Provider‬ﻫﺎﻱ ﻣﺎﻧﻨﺪ ‪ LINQ to SQL‬ﻭ ﻳﺎ‬
‫‪ LINQ to XML‬ﮐﻪ ﺗﻮﺳﻂ ﺗﻴﻢ ﺗﻮﺳﻌﻪ ‪ .NET‬ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺷﺪﻩ ﺍﻧﺪ ﮐﻪ ﺑﻪ ﺁﻥ ﻣﺪﻝ ‪ Provider‬ﺍﻃﻼﻕ ﻣﻲ ﺷﻮﺩ‪.ϱ‬‬

‫ﺍﻟﺒﺘﻪ ﺑﺮﺍﻱ ﺍﻳﻨﮑﻪ ﺗﻴﻢ ﺗﻮﺳﻌﻪ ﺩﻫﻨﺪﻩ ﻟﻴﻨﮏ ﺑﺘﻮﺍﻧﺪ ﻟﻴﻨﮏ ﺭﺍ ﻃﺮﺍﺣﻲ ﮐﻨﺪ ﻣﻲ ﺑﺎﻳﺴﺖ ﻳﮏ ﺳﺮﻱ ﻗﺎﺑﻠﻴﺖ ﻫﺎ ﺭﺍ ﺩﺭ ﺯﺑﺎﻥ‬
‫ﻫﺎﻱ ﺩﺍﺕ ﻧﺘﻲ ﺑﻮﺟﻮﺩ ﻣﻲ ﺁﻭﺭﺩ ﺗﺎ ﺑﺘﻮﺍﻥ ﭘﺮﺱ ﻭ ﺟﻮ ﻫﺎ ﺭﺍ ﺩﺭ ﻫﻤﻪ ﻱ ﺯﺑﺎﻥ ﻫﺎﻱ ﺩﺍﺕ ﻧﺘﻲ ﺑﻪ ﻳﮏ ﺻﻮﺭﺕ ﺗﻮﻟﻴﺪ ﻭ ﺍﺳﺘﻔﺎﺩﻩ‬

‫‪1‬‬
‫‪PDC Professional Developers Conference‬‬
‫‪2‬‬
‫‪Anders Hejlsberg‬‬
‫‪3‬‬
‫‪Collection‬‬
‫‪4‬‬
‫‪Query Expression‬‬
‫‪5‬‬
‫‪LINQ Provider Model‬‬
‫‪www.AliAghdam.ir‬‬ ‫‪LINQ‬‬ ‫ﺻﻔﺤﻪ ‪ | 3‬ﻓﺼﻞ ﺍﻭﻝ – ﺁﺷﻨﺎﻳﻲ ﺑﺎ‬

‫ﮐﺮﺩ ﺑﻪ ﻫﻤﻴﻦ ﺩﻟﻴﻞ ﺑﺎ ﻣﻌﺮﻓﻲ ﻟﻴﻨﮏ ﺗﮑﻨﻮﻟﻮﮊﻱ ﻫﺎﻱ ﺟﺪﻳﺪﻱ ﻫﻤﺎﻧﻨﺪ ﺗﻮﺍﺑﻊ ﺍﻟﺤﺎﻗﻲ ﮐﻪ ﮐﺎﺭﮐﺮﺩ ﺍﺻﻠﻲ ﻟﻴﻨﮏ ﺭﺍ ﺗﺤﻘﻖ ﻣﻲ‬
‫ﺩﻫﺪ ﻭ ﺗﻮﺍﺑﻊ ﺑﻲ ﻧﺎﻡ ‪ ،‬ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ﻭ ﭼﻨﺪﻱ ﺩﻳﮕﺮ ﮐﻪ ﺩﺭ ﻓﺼﻞ ﺑﻌﺪﻱ ﺑﻪ ﺑﺮﺭﺳﻲ ﻫﺮﻳﮏ ﺍﺯ ﺁﻧﻬﺎ ﺧﻮﺍﻫﻴﻢ ﭘﺮﺩﺍﺧﺖ‪.‬‬

‫ﺕﻭﺟﻪ‬
‫ﻫﺪﻑ ﺍﻳﻦ ﮐﺘﺎﺏ ﺁﻣﻮﺯﺵ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ‪ Provider‬ﻧﻴﺴﺖ ﻭﻟﻲ ﺑﺮﺍﻱ ﺁﺷﻨﺎﻳﻲ ﻣﻲ ﺗﻮﺍﻧﻴﺪ ﺑﻪ ﻣﻘﺎﻟﻪ ﺁﻗﺎﻱ ﭘﺪﺭﺍﻡ‬
‫‪U‬‬

‫ﺭﺿﺎﻳﻲ ﻣﺮﺍﺟﻌﻪ ﮐﻨﻴﺪ ) ‪.( http://tinyurl.com/LINQProviders‬‬


‫‪U‬‬ ‫‪U‬‬ ‫‪U‬‬

‫ﻧﻤﻮﺩﺍﺭ ﺯﻳﺮ ﺗﻮﺳﻂ ﺍﻋﻀﺎﻱ ﺗﻴﻢ ﺗﻮﺳﻌﻪ ﺩﺍﺕ ﻧﺖ ﻭ ‪ LINQ‬ﺗﻬﻴﻪ ﺷﺪﻩ ﺍﺳﺖ ﮐﻪ ﺑﻪ ﺧﻮﺑﻲ ﻧﺤﻮﻩ ﻋﻤﻠﮑﺮﺩ ﻭ ﻣﻌﻤﺎﺭﻱ ‪ LINQ‬ﺭﺍ‬
‫ﻧﺸﺎﻥ ﻣﻲ ﺩﻫﺪ‪.‬‬

‫ﺑﺎﻻ ﺗﺮﻳﻦ ﺳﻄﺢ ﻧﻤﻮﺩﺍﺭ ﻧﺸﺎﻥ ﺩﻫﻨﺪﻩ ﺯﺑﺎﻥ ﻫﺎﻱ ﺍﺳﺖ ﮐﻪ ﭘﺸﺘﻴﺒﺎﻧﻲ ﮐﺎﻣﻠﻲ ﺍﺯ ‪ LINQ‬ﺍﻧﺠﺎﻡ ﻣﻲ ﺩﻫﻨﺪ‪.‬‬

‫ﺳﻄﺢ ﻣﻴﺎﻧﻲ ﺍﻳﻦ ﻧﻤﻮﺩﺍﺭ ‪ 5‬ﺑﺨﺶ ﺍﺻﻠﻲ ﭘﺮﻭﮊﻩ ﻟﻴﻨﮏ ﺭﺍ ﻧﺸﺎﻥ ﻣﻲ ﺩﻫﺪ ‪:‬‬

‫‪ :LINQ to Objects‬ﻳﮏ ‪ API‬ﺍﺳﺖ ﻭ ﻣﺘﺪﻫﺎﻱ ﮐﻪ ﻧﺸﺎﻥ ﺩﻫﻨﺪﻩ ﻋﻤﻠﮕﺮ ﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ ﻣﻲ ﺑﺎﺷﻨﺪ ﺭﺍ‬
‫ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﺪ‪ .‬ﺍﻳﻦ ﻣﺘﺪﻫﺎ ﺑﺮﺍﻱ ﺑﺎﺯﻳﺎﺑﻲ ﺍﻃﻼﻋﺎﺕ ﺍﺯ ﺗﻤﺎﻣﻲ ﺍﺷﻴﺎﺋﻲ ﮐﻪ ﺭﺍﺑﻂ ‪ IEnumerable‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩﻩ‬
‫ﺑﺎﺷﻨﺪ ‪ ،‬ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ) ﺁﺭﺍﻳﻪ ﻭ ﻣﺠﻤﻮﻋﻪ ﻋﺎﻡ ﻭ ﻏﻴﺮ ﻋﺎﻡ ﺩﺭﻭﻥ ﺣﺎﻓﻈﻪ(‪.‬‬
‫‪ :LINQ to DataSet‬ﺍﻳﻦ ﻣﺪﻝ‪،‬ﺍﺯ ﻋﻤﻠﻴﺎﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﺑﺮ ﺭﻭﻱ ‪ DataTable‬ﻫﺎ ﻭ ‪ DataSet‬ﻫﺎﻱ ﻣﻮﺟﻮﺩ ﺩﺭ‬
‫‪ ADO.NET‬ﭘﺸﺘﻴﺒﺎﻧﻲ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫‪ :LINQ to SQL‬ﻧﺎﻣﻲ ﺍﺳﺖ ﮐﻪ ﺑﺮﺍﻱ ‪API‬ﻣﻌﻴﻦ ﺷﺪﻩ ﮐﻪ ﺑﻪ ﻭﺳﻴﻠﻪ ﺁﻥ ﺑﺎ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ ﺑﺎﻧﮏ ﻫﺎﻱ ﺭﺍﺑﻄﻪ ﺍﻱ ﻣﺎﻧﻨﺪ‬
‫‪ SQL Sever‬ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ‪.‬ﺑﻪ ﻃﻮﺭ ﺧﻼﺻﻪ ﺑﺎﻋﺚ ﺗﺴﻬﻴﻞ ﺩﺭ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺑﺎﻧﮏ ﺍﻃﻼﻋﺎﺗﻲ ﺭﺍ ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺑﺎﻧﮏ‬
‫|ﺻﻔﺤﻪ‪4‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﺍﻃﻼﻋﺎﺗﻲ ﺑﺮﺍﻱ ﭘﺮﺱ ﻭ ﺟﻮ ‪،‬ﺩﺭﺝ ‪،‬ﺣﺬﻑ ﻭ ﻭﻳﺮﺍﻳﺶ ﻣﻲ ﺷﻮﺩ‪ .‬ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ‪ LINQ to SQL‬ﻣﻲ ﺑﺎﻳﺴﺖ ﻳﮏ ﺍﺭﺟﺎﻉ‬
‫ﺑﻪ ﺍﺳﻤﺒﻠﻲ ‪ System.Data.Linq.dll‬ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ‪.‬‬
‫‪ :LINQ to Entities‬ﻳﮏ ﺭﺍﻩ ﺣﻞ ﺍﺭﺍﺋﻪ ﺷﺪﻩ ﺗﻮﺳﻂ ‪ Microsoft ORM‬ﻣﻲ ﺑﺎﺷﺪ ﻭ ﺗﻮﺳﻌﻪ ﻳﺎﻓﺘﻪ ‪LINQ to SQL‬‬
‫ﺍﺳﺖ‪ LINQ to Entities.‬ﺑﻴﻦ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻱ ﻓﻴﺰﻳﮑﻲ ﻭ ﻃﺮﺍﺣﻲ ﻣﻨﻄﻘﻲ ﻭ ﺗﺠﺎﺭﻱ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ ﻭ ﺍﺟﺎﺯﻩ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ‬
‫ﺁﻥ ﺭﺍ ﺑﻪ ﺻﻮﺭﺕ ﻣﻮﺟﻮﺩﻳﺖ� ﻫﺎ ﻣﻲ ﺩﻫﺪ )ﻣﻮﺟﻮﺩﻳﺖ ﻫﺎﻱ ﮐﻪ ﺷﺎﻳﺪ ﺍﺯ ﭼﻨﺪﻳﻦ ﺟﺪﻭﻝ ﺩﺭﺳﺖ ﺷﺪﻩ ﺑﺎﺷﻨﺪ(‪.‬‬
‫‪ :LINQ to XML‬ﻋﻼﻭﻩ ﺑﺮ ﺗﻌﻤﻴﻢ ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ ﺷﺎﻣﻞ ﻳﮏ ﺳﺮﻱ ﺧﺼﻮﺻﻴﺎﺕ ﻭﻳﮋﻩ ‪XML‬‬
‫ﺑﺮﺍﻱ ﺍﻳﺠﺎﺩ ﺍﺳﻨﺎﺩ ‪ XML‬ﻭ ﻫﻤﭽﻨﻴﻦ ﭘﺮﺱ ﻭ ﺟﻮ ﺑﺮ ﺭﻭﻱ ﺁﻧﻬﺎ ﻣﻲ ﺑﺎﺷﺪ ﺍﻟﺒﺘﻪ ﺗﻴﻢ ﺗﻮﺳﻌﻪ ﻟﻴﻨﮏ ﺧﺼﻮﺻﻴﺖ ﺟﺪﻳﺪﻱ‬
‫ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺍﺳﻨﺎﺩ ‪ XML‬ﻃﺮﺍﺣﻲ ﻧﮑﺮﺩﻩ ﺑﻠﮑﻪ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ‪ XML DOM‬ﺭﺍ ﭘﺸﺘﻴﺒﺎﻧﻲ ﮐﺮﺩﻩ ﺍﺳﺖ ﻳﻌﻨﻲ ﺩﻳﮕﺮ ﻧﻴﺎﺯﻱ‬
‫‪ LINQ to XML‬ﻣﻲ ﺑﺎﻳﺴﺖ ﻳﮏ ﺍﺭﺟﺎﻉ ﺑﻪ ﺍﺳﻤﺒﻠﻲ‬ ‫ﺑﻪ ﻳﺎﺩﮔﻴﺮﻱ ‪ XPath‬ﻧﺪﺍﺭﻳﺪ ‪.‬ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ‬
‫‪ System.Xml.Linq.dll‬ﺑﻪ ﭘﺮﻭﮊﻩ ﺍﺿﺎﻓﻪ ﮐﻨﻴﺪ‪.‬‬

‫ﺍﻟﺒﺘﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﺎﻥ ﻣﻲ ﺗﻮﺍﻧﻨﺪ ﺍﻳﻦ ‪ Provider‬ﻫﺎ ﺭﺍ ﺗﻮﺳﻌﻪ ﺩﻫﻨﺪ ﻭ ﻳﺎ ﺍﻳﻨﮑﻪ ﺑﺮﺍﻱ ﻣﺼﺎﺭﻑ ﺧﺎﺹ ﺍﺯ ‪ Provider‬ﻫﺎﻱ ﺭﺍ‬
‫ﺗﻮﺳﻌﻪ ﺩﺍﺩﻩ ﻭ ﺍﺯ ﺁﻧﻬﺎ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻨﺪ‪ .‬ﺩﺭ ﺯﻳﺮ ﻟﻴﺴﺘﻲ ﺍﺯ ‪ Provider‬ﻫﺎﻱ ﺗﻮﺳﻌﻪ ﻳﺎﻓﺘﻪ ﺑﻪ ﻫﻤﺮﺍﻩ ﻟﻴﻨﮏ ﻣﺮﺑﻮﻃﻪ‪ ،‬ﻣﻮﺟﻮﺩ ﺍﺳﺖ ‪:‬‬

‫‪6‬‬
‫‪Entities‬‬
LINQ Extender
LINQ over C# project
U U

LINQ to Active Directory


U U

LINQ to Amazon
U U

LINQ to CRM
U U

LINQ to Excel
U U

LINQ to Expressions
U U

LINQ to Flickr
U U

LINQ to Geo
U U

LINQ to Google
U U

LINQ to Indexes
LINQ to JavaScript
U U

LINQ to JSON
U U

LINQ to LDAP
U U

LINQ to LLBLGen Pro


U U

LINQ to Lucene
U U

LINQ to Metaweb
U U

LINQ to MySQL
LINQ to NCover
LINQ to NHibernate
U U

LINQ to Opf3
LINQ to Parallel (PLINQ (
U U

LINQ to RDF Files


U U

LINQ to Sharepoint
U U

LINQ to SimpleDB
U U

LINQ to Streams
U U

LINQ to WebQueries
LINQ to WMI
U U

‫ﻣﺪﻝ ﺭﺍﺑﻄﻪ ﺍﻱ ﺩﺍﺭﺍﻱ ﻣﺰﺍﻳﺎﻳﻲ ﺍﺳﺖ ﮐﻪ ﺩﺭ ﻧﮕﺎﻩ ﺍﻭﻝ ﻣﺘﻮﺟﻪ ﺁﻥﻫﺎ ﻧﻤﻲ ﺷﻮﻳﻢ ﻭﻟﻲ ﺑﺎ ﻧﮕﺮﺵ ﺩﺭ ﺁﻥ ﺑﻪ ﺍﻳﻦ ﻣﺰﺍﻳﺎ ﻭﺍﻗﻒ ﻣﻲ‬
.‫ﺷﻮﻳﻢ‬

.‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﻲ ﺗﻮﺍﻧﺪ ﺑﺎ ﺗﺼﻮﺭ ﺧﻮﺩ ﮐﻮﺋﺮﻱ ﻃﺮﺍﺣﻲ ﮐﻨﺪ ﻭ ﺁﻧﻬﺎ ﺭﺍ ﺑﻪ ﺻﻮﺭﺕ ﺑﺼﺮﻱ ﻭﻳﺮﺍﻳﺶ ﮐﻨﺪ‬
‫ﺑﺎ ﻓﺮﺍﻫﻢ ﺷﺪﻥ ﮔﺰﻳﻨﻪ ﻗﺒﻞ ﺷﺮﺍﻳﻄﻲ ﺑﻮﺟﻮﺩ ﻣﻲ ﺁﻳﺪ ﮐﻪ ﮐﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﻲ ﺗﻮﺍﻧﺪ ﮐﻮﺋﺮﻱ ﺧﻮﺩ ﺭﺍ ﺑﻪ ﺣﺪﺍﮐﺜﺮ‬
.‫ﮐﺎﺭﺍﻳﻲ ﺧﻮﺩ ﺑﺮﺳﺎﻧﺪ ﭼﻮﻥ ﮐﻮﺋﺮﻱ ﺭﺍ ﻣﺸﺎﻫﺪﻩ ﻣﻲ ﮐﻨﺪ‬
‫|ﺻﻔﺤﻪ‪2‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻣﻲ ﺗﻮﺍﻧﺪ ‪ Provider‬ﻱ ﺑﺮﺍﻱ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺧﻮﺩ ﻃﺮﺍﺣﻲ ﮐﻨﺪ ﺗﺎ ﺩﻳﮕﺮﺍﻥ ﺑﺎ ﺁﻥ ﺑﻪ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺍﻭ ﺩﺳﺘﺮﺳﻲ‬
‫ﺩﺍﺷﺘﻪ ﺑﺎﺷﻨﺪ ﺑﻪ ﻃﻮﺭ ﻣﺜﺎﻝ ﺍﮔﺮ ﺷﻤﺎ ﻳﮏ ‪ web service‬ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻭ ﺑﺨﻮﺍﻫﻴﺪ ﮐﺎﺭﺑﺮﺍﻥ ﺗﺤﺖ ﻳﮏ ﺳﻴﺴﺘﻢ ﺑﻪ‬
‫ﺁﻥ ﺩﺳﺘﺮﺳﻲ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻨﺪ ﺑﺮﺍﻱ ﺍﻳﻦ ﻣﻨﻄﻮﺭ ﻣﻲ ﺗﻮﺍﻧﻴﺪ ﻳﮏ ‪ Provider‬ﻃﺮﺍﺣﻲ ﮐﻨﻴﺪ‪.‬‬

‫ﺍﺳﻤﺒﻠﻲ ﻫﺎﻱ ﻣﺮ ﮐﺰﻱ ‪:LINQ‬‬

‫‪ :System.Core.dll‬ﺍﻧﻮﺍﻋﻲ ﺭﺍ ﺗﻌﺮﻳﻒ ﻣﻲ ﮐﻨﺪ ﮐﻪ ‪ LINQ API‬ﻣﺮﮐﺰﻱ ﺭﺍ ﻧﻤﺎﻳﺶ ﻣﻲ ﺩﻫﻨﺪ‪ .‬ﺍﻳﻦ ﻳﮑﻲ ﺍﺯ‬
‫ﺍﺳﻤﺒﻠﻲ ﻫﺎﻱ ﺍﺳﺖ ﮐﻪ ﺷﻤﺎ ﺑﺎﻳﺪ ﺑﻪ ﺁﻥ ﺍﺭﺟﺎﻉ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ‪.‬‬
‫‪ : System.Data.Linq.dll‬ﮐﺎﺭﺍﻳﻲ ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ‪ LINQ‬ﺑﺎ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻫﺎﻱ ﺭﺍﺑﻄﻪ ﺍﻱ ﺭﺍ ﻣﻬﻴﺎ ﻣﻲ‬
‫ﮐﻨﺪ‪(LINQ to SQL).‬‬
‫‪ : System.Xml.Ling.dll‬ﮐﺎﺭﺍﻳﻲ ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ‪ LINQ‬ﺑﺎ ﺍﺳﻨﺎﺩ ‪ XML‬ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﺪ‪LINQ to ).‬‬
‫‪(XML‬‬
‫‪www.AliAghdam.ir‬‬ ‫‪LINQ‬‬ ‫ﺻﻔﺤﻪ ‪ | 3‬ﻓﺼﻞ ﺍﻭﻝ – ﺁﺷﻨﺎﻳﻲ ﺑﺎ‬

‫ﻧﻮﺷﺘﻦ ﺍﻭﻟﻴﻦ ﺑﺮﻧﺎﻣﻪ ﺗﻮﺳﻂ ‪LINQ‬‬


‫ﺑﺮﺍﻱ ﻧﻮﺷﺘﻦ ﺍﻭﻟﻴﻦ ﺑﺮﻧﺎﻣﻪ ﻟﻴﻨﮏ ﺧﻮﺩ ﻳﮏ ﺑﺮﻧﺎﻣﻪ ﮐﻨﺴﻮﻝ ﺍﻳﺠﺎﺩ ﮐﻨﻴﺪ ﻭ ﺳﭙﺲ ﮐﺪ ﺯﻳﺮ ﺭﺍ ﺩﺭ ﺁﻥ ﺑﻨﻮﻳﺴﻴﺪ ‪:‬‬

‫;‪using System‬‬
‫;‪using System.Linq‬‬
‫;} "‪string[] myWords = { "hello world", "hello LINQ", "hello Aghdam‬‬
‫= ‪var items‬‬
‫‪from item in myWords‬‬
‫)"‪where item.EndsWith("LINQ‬‬
‫;‪select item‬‬

‫)‪foreach (var item in items‬‬


‫;)‪Console.WriteLine(item‬‬

‫ﺍﮔﺮ ﮐﺪ ﺑﺎﻻ ﺭﺍ ﺍﺟﺮﺍ ﮐﻨﻴﺪ ﺧﺮﻭﺟﻲ ﺑﺮﺍﺑﺮ ﺑﺎ ‪ hello LINQ‬ﺧﻮﺍﻫﺪ ﺑﻮﺩ!‬

‫ﻫﻤﺎﻧﻄﻮﺭ ﮐﻪ ﻣﺸﺎﻫﺪﻩ ﻓﺮﻣﻮﺩﻳﺪ ﻋﺒﺎﺭﺕ ﮐﻮﺋﺮﻱ ﺑﺎﻻ ﺑﺴﻴﺎﺭ ﺷﺒﻴﻪ ﺑﻪ ﮐﻮﺋﺮﻱ ﻫﺎﻱ ‪ SQL‬ﺍﺳﺖ ‪،‬ﺣﺎﻻ ﻣﻲ ﺧﻮﺍﻫﻴﻢ ﻗﺴﻤﺖ ﻫﺎﻱ‬
‫ﺍﻳﻦ ﮐﺪ ﺭﺍ ﺷﺮﺡ ﺩﻫﻴﻢ ﻭ ﺍﮔﺮ ﺑﺎ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﺎ ﺁﺷﻨﺎ ﻧﻴﺴﺘﻴﺪ ﺩﺭ ﻓﺼﻮﻝ ﺑﻌﺪﻱ ﺑﺎ ﺁﻧﻬﺎ ﺁﺷﻨﺎ ﺧﻮﺍﻫﻴﺪ ﺷﺪ‪.‬‬

‫ﺩﺭ ﻗﺴﻤﺖ ﮐﻮﺋﺮﻱ ﻳﮏ ﻣﺘﻐﻴﺮ ﺍﺯ ﻧﻮﻉ ‪ var‬ﺑﻪ ﻧﺎﻡ ‪ items‬ﺗﻌﺮﻳﻒ ﺷﺪﻩ ﺍﺳﺖ ﮐﻪ ﺑﺮﺍﻱ ﺧﺮﻭﺟﻲ ﮐﻮﺋﺮﻱ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ‬
‫ﻣﻲ ﮔﻴﺮﺩ ‪ ،‬ﺳﭙﺲ ‪ items‬ﺗﻮﺳﻂ ﻳﮏ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮﻱ ‪ LINQ‬ﻣﻘﺪﺍﺭﺩﻫﻲ ﺍﻭﻟﻴﻪ ﺷﺪﻩ ﺍﺳﺖ‪ .‬ﺩﺭ ﻗﺴﻤﺖ ﺍﻭﻝ ﺍﺯ ﻋﺒﺎﺭﺕ‬
‫ﭘﺮﺱ ﻭ ﺟﻮ ‪ from،‬ﺑﺮﺍﻱ ﺗﻌﻴﻴﻦ ﻧﺎﻡ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ ‪ .‬ﻣﺘﻐﻴﺮ ‪ item‬ﺩﺭ ﻋﺒﺎﺭﺕ ﻧﺸﺎﻧﮕﺮ ﻳﮏ ﻋﻀﻮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ‬
‫‪ items‬ﺍﺳﺖ ‪.‬‬

‫ﺩﺭ ﻗﺴﻤﺖ ‪ where‬ﺷﺮﻁ ﻫﺎﻱ ﻻﺯﻡ ﺑﺮﺍﻱ ﺑﺎﺯﻳﺎﺑﻲ ﺍﻃﻼﻋﺎﺕ ﺍﺯ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺗﺒﻴﻴﻦ ﺷﺪﻩ ﺍﺳﺖ ﮐﻪ ﺗﺎﺑﻊ ‪ Endwith‬ﺍﺯ ﮐﻼﺱ‬
‫‪ string‬ﻓﺮﺍﺧﻮﺍﻧﻲ ﺷﺪﻩ ﮐﻪ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻗﺴﻤﺖ ﭘﺎﻳﺎﻧﻲ ﺭﺷﺘﻪ ﺑﺎ " ‪ "LINQ‬ﺑﻪ ﭘﺎﻳﺎﻥ ﺑﺮﺳﺪ ‪،‬ﺍﻳﻦ ﺗﺎﺑﻊ ﻣﻘﺪﺍﺭ ‪ true‬ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‬
‫ﻭ ﺳﺮﺍﻧﺠﺎﻡ ﺩﺭ ﻗﺴﻤﺖ ‪، select‬ﻗﺴﻤﺖ ﻫﺎ ‪ /‬ﺑﺨﺶ ﻫﺎ ‪ /‬ﻳﺎ ﻓﻴﻠﺪ ﻫﺎﻱ ﮐﻪ ﻣﻲ ﺧﻮﺍﻫﻴﻢ ﻧﻤﺎﻳﺶ ﺩﻫﻴﻢ ﺭﺍ ﺍﻧﺘﺨﺎﺏ ﻣﻲ ﮐﻨﻴﻢ‪.‬‬
‫ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫‪2‬‬ ‫ﻫﻤﺎﻧﻄﻮﺭ ﮐﻪ ﺩﺭ ﻓﺼﻞ ﻗﺒﻞ ﮔﻔﺘﻴﻢ ‪ LINQ‬ﺗﻮﺍﻧﺎﻳﻲ ﺧﻮﺩ ﺭﺍ ﺑﻮﺳﻴﻠﻪ ﻗﺎﺑﻠﻴﺖ ﻫﺎﻱ ﺟﺪﻳﺪﻱ ﺑﻪ ﺩﺳﺖ ﻣﻲ ﺁﻭﺭﺩ‬
‫ﮐﻪ ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ‪ LINQ‬ﻣﻲ ﺑﺎﻳﺴﺖ ﺍﺯ ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﻢ ‪،‬ﺑﺮﺍﻱ ﺍﻳﻨﮑﻪ ﺑﺘﻮﺍﻧﻴﻢ ﺩﺭﮎ‬
‫ﺑﻬﺘﺮﻱ ﺍﺯ ﻋﺒﺎﺭﺍﺕ ‪ LINQ‬ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﻢ ﻻﺯﻡ ﺍﺳﺖ ﺗﺎ ﺍﻳﻦ ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ﺭﺍ ﮐﻪ ﺩﺭ ‪ C# 2.0‬ﻭ ‪ C# 3.0‬ﺑﻪ ﺯﺑﺎﻥ ‪#C‬‬
‫ﺍﺿﺎﻓﻪ ﮔﺮﺩﻳﺪﻩ ﺭﺍ ﻓﺮﺍ ﺑﮕﻴﺮﻳﻢ‪.‬‬

‫ﺍﻳﻦ ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ﻋﺒﺎﺭﺗﻨﺪ ﺍﺯ‪:‬‬

‫ﻧﻮﻉ ﻫﺎﻱ ﺑﻲ ﻧﺎﻡ ‪Anonymous types -‬‬


‫ﻣﻘﺪﺍﺭ ﺩﻫﻨﺪﻩ ﺍﻭﻟﻴﻪ ﺑﻪ ﺍﺷﻴﺎﺀ ‪Object Initializers -‬‬
‫ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ ‪Type Inference -‬‬
‫ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ‪Extension Methods -‬‬
‫ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ‪Lambda Expressions -‬‬
‫ﻋﺒﺎﺭﺍﺕ ﭘﺮﺱ ﻭ ﺟﻮ ‪Query Expresions -‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 5‬ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫ﻧﻮﻉ ﻫﺎﻱ ﺑﻲ ﻧﺎﻡ ‪Anonymous types -‬‬

‫ﺷﻤﺎ ﺑﻪ ﻋﻨﻮﺍﻥ ﻳﮏ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ‪ ، OO‬ﻣﺰﺍﻳﺎﻱ ﺗﻌﺮﻳﻒ ﮐﻼﺱ ﻫﺎ ﺑﺮﺍﻱ ﻧﻤﺎﻳﺶ ﺟﺰﺋﻴﺎﺕ ﻭ ﮐﺎﺭﺍﻳﻲ ﻳﮏ ﻣﻮﺟﻮﺩﻳﺖ‬
‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺭﺍ ﻣﻲ ﺩﺍﻧﻴﺪ ‪.‬ﻫﺮ ﻭﻗﺖ ﺷﻤﺎ ﻧﻴﺎﺯ ﺑﻪ ﺗﻌﺮﻳﻒ ﻳﮏ ﮐﻼﺱ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ‪ ،‬ﺁﻥ ﺭﺍ ﺗﻌﺮﻳﻒ ﻭ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻣﻲ ﮐﻨﻴﺪ‬
‫ﻭﻟﻲ ﻫﻨﮕﺎﻣﻲ ﮐﻪ ﺷﻤﺎ ﻣﻲ ﺧﻮﺍﻫﻴﺪ ﻣﻲ ﺧﻮﺍﻫﻴﺪ ﮐﻼﺳﻲ ﺭﺍ ﺑﺮﺍﻱ ﻣﺪﻟﺴﺎﺯﻱ ﻣﺠﻤﻮﻋﻪ ﺍﻱ ﺍﺯ ﺩﺍﺩﻩ ﻫﺎﻱ ﮐﭙﺴﻮﻟﻪ ﺷﺪﻩ ﺑﺪﻭﻥ‬
‫ﺗﺎﺑﻊ‪ ،‬ﺭﻭﻳﺪﺍﺩ ﻭ ﻳﺎ ﮐﺎﺭﺍﻳﻲ ﺳﻔﺎﺭﺷﻲ ﺩﻳﮕﺮﻱ ﺍﻳﺠﺎﺩ ﮐﻨﻴﺪ ﻭ ﺣﺘﻲ ﺍﻳﻦ ﻣﺪﻝ ﺳﺎﺯﻱ ﻓﻘﻂ ﺩﺭﻭﻥ ﭘﺮﻭﮊﻩ ﺷﻤﺎ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ‬
‫ﮔﺮﻓﺘﻪ ﺑﺎﺷﺪ ﻭ ﺩﻳﮕﺮ ﻗﺼﺪ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺁﻥ ﺭﺍ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ‪،‬ﭼﮑﺎﺭ ﺍﻧﺠﺎﻡ ﻣﻲ ﺩﻫﻴﺪ¿ ﺁﻳﺎ ﮐﻼﺱ ﺟﺪﻳﺪﻱ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﻴﺪ ؟‬

‫ﺍﻳﻨﺠﺎﺳﺖ ﮐﻪ ﻧﻮﻉ ﻫﺎﻱ ﺑﻲ ﻧﺎﻡ ﺑﻪ ﮐﻤﮏ ﺷﻤﺎ ﻣﻲ ﺁﻳﻨﺪ ﻭ ﻳﮏ ﻣﻴﺎﻥ ﺑﺮ ﺑﺴﻴﺎﺭ ﺑﺰﺭﮒ ﺭﺍ ﺩﺭ ﺟﻠﻮﻱ ﭘﺎﻱ ﺷﻤﺎ ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ‪.‬‬
‫ﻭﻗﺘﻲ ﻣﻲ ﺧﻮﺍﻫﻴﺪ ﻳﮏ ﻧﻮﻉ ﺑﻲ ﻧﺎﻡ ﺍﻳﺠﺎﺩ ﮐﻨﻴﺪ ﺍﻳﻦ ﮐﺎﺭ ﺭﺍ ﺑﺎ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﮐﻠﻤﻪ ﮐﻠﻴﺪﻱ ‪ var‬ﺍﻧﺠﺎﻡ ﻣﻲ ﺩﻫﻴﺪ‪ .‬ﻧﻮﻉ ﻫﺎﻱ ﺑﻲ‬
‫ﻧﺎﻡ ﺍﻳﻦ ﻗﺎﺑﻠﻴﺖ ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﻨﺪ ﮐﻪ ﺍﻧﻮﺍﻉ ﻗﻮﻱ ﻧﻮﻉ ﺑﻨﺪﻱ ﺷﺪﻩ ﺭﺍ ﺑﺪﻭﻥ ﻧﻴﺎﺯ ﺑﻪ ﺍﻳﺠﺎﺩ ﮐﻼﺱ ﻫﺎ‪ ،‬ﺍﻳﺠﺎﺩ ﮐﻨﻴﺪ‪.‬‬

‫ﺩﺭ ‪ LINQ‬ﺍﺯ ﻧﻮﻉ ﻫﺎﻱ ﺑﻲ ﻧﺎﻡ ﺍﺳﺘﻔﺎﻩ ﺯﻳﺎﺩﻱ ﻣﻲ ﺷﻮﺩ ﭼﻮﻥ ﭘﺎﺳﺦ ﭘﺮﺱ ﻭ ﺟﻮﻫﺎ ﻣﻤﮑﻦ ﺍﺳﺖ ﻫﺮ ﻧﻮﻋﻲ ﺑﺎﺷﺪ ﻭ ﺍﺯ ﺁﻧﻬﺎ‬
‫ﺑﻪ ﻋﻨﻮﺍﻥ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﻣﻮﻗﺘﻲ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‪.‬‬

‫ﺑﻪ ﻣﺜﺎﻝ ﺯﻳﺮ ﺗﻮﺟﻪ ﮐﻨﻴﺪ‪.‬‬

‫)‪static void Main(string[] args‬‬


‫{‬
‫"‪var person = new { ID = 1, FName = "Ali", LName = "Aghdam", Job = "Student‬‬
‫;}‬

‫‪Console.WriteLine("The Person‬‬ ‫‪Name is {0} {1}.", person.FName,‬‬


‫;)‪person.LName‬‬

‫;)(‪Console.ReadLine‬‬
‫}‬

‫ﺩﺭ ﻋﺒﺎﺭﺕ ﺑﺎﻻ ﺑﻌﺪ ﺍﺯ ﮐﻠﻤﻪ ﮐﻠﻴﺪﻱ ‪ new‬ﻫﻴﭻ ﮔﻮﻧﻪ ﻧﻮﻋﻲ ﺗﻌﻴﻴﻦ ﻧﺸﺪﻩ ﮐﻪ ﮐﺎﻣﭙﺎﻳﻠﺮ ﻳﮏ ﻧﻮﻉ ﺑﻲ ﻧﺎﻡ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫ﻧﻮﻉ ﻫﺎﻱ ﺑﻲ ﻧﺎﻡ ﺑﻪ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﺍﺟﺎﺯﻩ ﻣﻲ ﺩﻫﺪ ﮐﻪ ﺍﺯ ﺧﺮﻭﺟﻲ ﭘﺮﺱ ﻭ ﺟﻮ ﻫﺎ ﺑﺪﻭﻥ ﻧﻴﺎﺯ ﺑﻪ ﺳﺎﺧﺖ ﮐﻼﺱ ﺟﺪﻳﺪ‪ ،‬ﺍﺳﺘﻔﺎﺩﻩ‬
‫ﮐﻨﻨﺪ‪.‬‬
‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ ‪| LINQ‬ﺻﻔﺤﻪ ‪6‬‬ ‫‪www.AliAghdam.ir‬‬

‫ﻣﻘﺪﺍﺭ ﺩﻫﻨﺪﻩ ﺍﻭﻟﻴﻪ ﺑﻪ ﺍﺷﻴﺎﺀ ‪Object Initializers -‬‬

‫ﺍﻣﺮﻭﺯﻩ ﺩﺭ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺑﺮﺍﻱ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻣﻮﺟﻮﺩﻳﺖ ﻫﺎ ﺍﺯ ﮐﻼﺱ ﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﮐﻨﻴﻢ ﮐﻪ ﺩﺭ ﻣﻬﻨﺪﺳﻲ ﻧﺮﻡ ﺍﻓﺰﺍﺭ ﺑﻪ ﺍﻳﻦ‬
‫ﺭﻭﺵ ‪ Entity Types‬ﺍﻃﻼﻕ ﻣﻲ ﺷﻮﺩ ﻭ ﺑﻪ ﻋﻨﻮﺍﻥ ﺑﺴﺘﻪ ﻫﺎﻱ ﺍﻃﻼﻋﺎﺗﻲ ﻣﺤﺴﻮﺏ ﻣﻲ ﺷﻮﻧﺪ ﻭﻟﻲ ﺩﺭ ﻃﻲ ﺍﻳﻦ ﺍﻣﺮ‬
‫ﻣﺸﮑﻼﺗﻲ ﻭﺟﻮﺩ ﺩﺍﺭﺩ ﮐﻪ ﻳﮑﻲ ﺍﺯ ﺁﻥ ﻫﺎ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺳﺎﺯﻧﺪﻩ ﻫﺎﻱ ﻣﺨﺘﻠﻒ ﺍﺳﺖ‪ .‬ﺑﺎ ﻗﺎﺑﻠﻴﺖ ﺟﺪﻳﺪ ﺳﻲ ﺷﺎﺭﭖ ﻳﻌﻨﻲ ﻣﻘﺪﺍﺭ‬
‫ﺩﻫﻨﺪﻩ ﺍﻭﻟﻴﻪ ﺑﻪ ﺍﺷﻴﺎﺀ ﻣﻲ ﺗﻮﺍﻥ ﺗﺎ ﺣﺪ ﺑﺴﻴﺎﺭ ﺯﻳﺎﺩﻱ ﺍﺯ ﺍﻳﻦ ﭘﻴﭽﻴﺪﮔﻲ ﺟﻠﻮﮔﻴﺮﻱ ﮐﺮﺩ ﻭ ﻫﻤﭽﻨﻴﻦ ﺗﺎ ﺣﺪ ﺯﻳﺎﺩﻱ ﺍﺯ ﺑﺎﺭ‬
‫ﮐﺪﻧﻮﻳﺴﻲ ﮐﺎﺳﺖ ﺑﻪ ﻃﻮﺭﻱ ﮐﻪ ﻣﻲ ﺗﻮﺍﻥ ﺩﺭ ﻫﻨﮕﺎﻡ ﺍﻳﺠﺎﺩ ﻧﻤﻮﻧﻪ ﺍﺯ ﮐﻼﺱ ﺑﻪ ﻓﻴﻠﺪ ﻫﺎﻱ ﻋﻤﻮﻣﻲ ﻭ ‪ Property‬ﻫﺎ‬
‫ﺩﺳﺘﺮﺳﻲ ﭘﻴﺪﺍ ﮐﺮﺩﻩ ﻭ ﺑﻪ ﺻﻮﺭﺕ ﺳﻔﺎﺭﺷﻲ ﺁﻧﻬﺎ ﺭﺍ ﻣﻘﺪﺍﺭ ﺩﻫﻲ ﻧﻤﻮﺩ‪.‬‬

‫ﺑﻪ ﻃﻮﺭ ﻣﺜﺎﻝ ﻣﻮﺟﻮﺩﻳﺖ ‪ Person‬ﺭﺍ ﺑﺎ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺯﻳﺮ ﺩﺭ ﻧﻄﺮ ﺑﮕﻴﺮﻳﺪ‪..‬‬

‫‪class Person‬‬
‫{‬
‫‪public int ID‬‬
‫} ;‪{ get; set‬‬

‫‪public string FName‬‬


‫} ;‪{ get; set‬‬

‫‪public string LName‬‬


‫} ;‪{ get; set‬‬
‫}‬

‫ﺧﻮﺏ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻣﻮﺟﻮﺩﻳﺖ ﺑﺎﻻ ﮐﻪ ﺳﻪ ﺷﻨﺎﺳﻪ ﺭﺍ ﺗﻌﺮﻳﻒ ﮐﺮﺩﻩ ‪،‬ﺳﺎﺯﻧﺪﻩ ﺑﻪ ﭼﻪ ﺷﮑﻠﻲ ﺧﻮﺍﻫﺪ ﺑﻮﺩ ¿‬
‫ﺍﮔﺮ ﺍﺯ ﻣﻦ ﺑﭙﺮﺳﻴﺪ ﻣﻲ ﮔﻮﻳﻢ ﻫﻴﭻ ﻧﻴﺎﺯﻱ ﺑﻪ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺳﺎﺯﻧﺪﻩ ﺩﺭ ﻣﻮﺭﺩ ﮐﻼﺱ ﺑﺎﻻ ﻧﻴﺴﺖ! ﺑﻪ ﭼﻪ ﺷﮑﻞ ¿ ﺑﻪ ﺷﮑﻞ ﺯﻳﺮ ‪:‬‬

‫‪Person person = new Person‬‬


‫{‬
‫‪ID = 1,‬‬
‫‪FName = "Ali",‬‬
‫"‪Lname = "Aghdam‬‬
‫;}‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 7‬ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫ﻭ ﺣﺘﻲ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ‪:‬‬

‫‪Person person = new Person‬‬


‫{‬
‫‪ID = 1,‬‬
‫"‪Lname = "Aghdam‬‬
‫;}‬

‫ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ ‪Type Inference -‬‬

‫ﮐﻠﻤﻪ ﮐﻠﻴﺪﻱ ‪) var‬ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ(ﺑﻪ ﮐﺎﻣﭙﺎﻳﻠﺮ ﺍﻋﻼﻡ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﺧﻮﺩﺵ ﺩﺭ ﻣﻮﺭﺩ ﻧﻮﻉ ﻣﺘﻐﻴﺮ ﺗﺼﻤﻴﻢ ﮔﻴﺮﻱ ﻣﻲ ﮐﻨﺪ‬
‫ﻭ ﻫﻴﭻ ﻣﻮﻗﻊ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺲ ﻧﻤﻲ ﺗﻮﺍﻧﺪ ﺑﻪ ﺻﻮﺭﺕ ﺻﺮﻳﺢ ﻧﻮﻉ ﺁﻥ ﺭﺍ ﻣﺸﺨﺺ ﮐﻨﺪ ﺍﻟﺒﺘﻪ ﺍﻳﻦ ﺗﺼﻤﻴﻢ ﮔﻴﺮﻱ ﺑﺮﺍﻱ ﻧﻮﻉ ﻣﺘﻐﻴﺮ ﺩﺭ‬
‫ﺯﻣﺎﻥ ﺍﺳﺘﻔﺎﺩﻩ ﻭ ﻣﻘﺪﺍﺭﺩﻫﻲ ﺷﺪﻥ ﺍﻧﺠﺎﻡ ﻣﻲ ﮔﻴﺮﺩ‪ .‬ﻧﻤﻮﻧﻪ ﺯﻳﺮ ﻳﮏ ﻣﺜﺎﻝ ﺳﺎﺩﻩ ﺍﺯ ‪ var‬ﺭﺍ ﻧﺸﺎﻥ ﻣﻲ ﺩﻫﺪ‪.‬‬

‫;‪var i = 1‬‬
‫‪i = "Hello LINQ"; // An error generated by this line‬‬

‫ﺗﻮﺿﻴﺢ‪ :‬ﺩﺭ ﺧﻂ ﺍﻭﻝ ﺑﺎ ﻣﻘﺪﺍﺭ ﺩﻫﻲ ‪ 1‬ﺑﻪ ﻣﺘﻐﻴﺮ ‪ i‬ﮐﺎﻣﭙﺎﻳﻠﺮ ﻧﻮﻉ ﻣﺘﻐﻴﺮ ‪ i‬ﺭﺍ ﺍﺯ ﻧﻮﻉ ‪ System.Int32‬ﺩﺭ ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﺩ‪،‬‬
‫ﺑﺎ ﺍﻳﻦ ﺍﻭﺻﺎﻑ ﻣﻨﻄﻘﻲ ﺍﺳﺖ ﮐﻪ ﺍﺯ ﺧﻂ ﺩﻭﻡ ﺧﻄﺎ ﺩﺍﺷﺘﻪ ﺑﺎﺷﺪ‪.‬‬

‫ﺑﻴﺸﺘﺮ ﺑﺪﺍﻧﻴﻢ‬
‫ﺩﺭ ﺍﺻﻞ ‪ var‬ﻳﮏ ﮐﻠﻤﻪ ﮐﻠﻴﺪﻱ ‪ C#‬ﻧﻴﺴﺖ ﻭﻟﻲ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ ﺍﻳﻦ ﺗﻮﮐﻦ ﺑﺪﻭﻥ ﺭﺥ ﺩﺍﺩﻥ ﺧﻄﺎ ﺑﻪ ﻋﻨﻮﺍﻥ ﻳﮏ ﻧﻮﻉ ﺩﺍﺩﻩ‬
‫ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ ﺍﻣﺎ ﺩﺭ ﻫﻨﮕﺎﻡ ﮐﺎﻣﭙﺎﻳﻞ ﺷﺪﻥ ﮐﺪ‪ ،‬ﮐﺎﻣﭙﺎﻳﻠﺮ ﺁﻥ ﺭﺍ ﺍﺯ ﺭﻭﻱ ﻗﺮﺍﻳﻦ ﺑﻪ ﻋﻨﻮﺍﻥ ﻳﮏ ﮐﻠﻤﻪ ﮐﻠﻴﺪﻱ ﻣﻲ ﺷﻨﺎﺳﺪ‪.‬‬

‫ﺍﺯ ﺍﻳﻦ ﻗﺎﺑﻠﻴﺖ ﻣﻲ ﺗﻮﺍﻥ ﺑﺮﺍﻱ ﮔﺎﻫﺶ ﺗﮑﺮﺍﺭ ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ ﻣﺜﻼ ﮐﺪ ﺯﻳﺮ ﺭﺍ ﺩﺭ ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ‪:‬‬

‫;)‪List<int> myNumbers = new List<int>(1, 2, 3‬‬


‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ ‪| LINQ‬ﺻﻔﺤﻪ ‪8‬‬ ‫‪www.AliAghdam.ir‬‬

‫ﺩﺭ ﮐﺪ ﺑﺎﻻ ﻣﺎ ﻧﻴﺎﺯﻱ ﺑﻪ ﻗﻴﺪ ﮐﺮﺩﻥ ﺻﺮﻳﺢ >‪ List<int‬ﺩﺭ ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﺮ ‪ myNumbers‬ﻧﺪﺍﺷﺘﻴﻢ ﻭ ﻣﻲ ﺗﻮﺍﻧﻴﻢ ﺁﻥ‬
‫ﮐﺪ ﺭﺍ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﻭ ﮐﻮﺗﺎﻩ ﺗﺮ ﺑﻨﻮﻳﺴﻴﻢ‪.‬‬

‫;)‪var myNumbers = new List<int>(1, 2, 3‬‬

‫ﻧﮑﺘﻪ‬
‫ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﺍﻳﻦ ﻋﻤﻞ ﺭﺍ ﻃﻮﺭﻱ ﺍﻧﺠﺎﻡ ﺩﻫﻴﺪ ﺗﺎ ﺩﺭ ﻫﻨﮕﺎﻡ ﻣﺮﺍﺟﻌﻪ ﺩﻭﺑﺎﺭﻩ ﺑﻪ ﮐﺪ ﺑﺘﻮﺍﻧﻴﺪ ﻧﺤﻮﻩ ﻭ ﻧﻮﻉ ﻣﺘﻐﻴﺮﺭﺍ‬
‫ﺗﺸﺨﻴﺺ ﺩﻫﻴﻢ‪.‬‬

‫ﺩﺭ ﻫﻨﮕﺎﻡ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ ﻣﺤﻮﺩﻳﺖ ﻫﺎﻱ ﻭﺟﻮﺩ ﺩﺍﺭﺩ ﮐﻪ ﺩﺭ ﺯﻳﺮ ﺑﻪ ﻣﻌﺮﻓﻲ ﺁﻧﻬﺎ ﻣﻲ ﭘﺮﺩﺍﺯﻡ‪:‬‬

‫ﺍﻭﻟﻴﻦ ﻭ ﻣﻬﻢ ﺗﺮﻳﻦ ﻣﺤﺪﻭﺩﻳﺖ ﺍﻳﻦ ﮐﻪ ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ ﺗﻨﻬﺎ ﺑﻪ ﻣﺘﻐﻴﺮ ﻫﺎﻱ ﺩﺭﻭﻥ ﻳﮏ ﺗﺎﺑﻊ ﻳﺎ ﺧﺼﻮﺻﻴﺖ ﺍﻋﻤﺎﻝ ﻣﻲ‬
‫ﺷﻮﺩ‪ .‬ﺑﻨﺎﺑﺮﺍﻳﻦ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﮐﻠﻤﻪ ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ ﺑﺮﺍﻱ ﺗﻌﺮﻳﻒ ﻣﻘﺎﺩﻳﺮ ﺑﺎﺯﮔﺸﺘﻲ‪ ،‬ﭘﺎﺭﺍﻣﺘﺮﻫﺎ ﻭ ﻳﺎ ﺩﺍﺩﻩ ﻫﺎﻱ ﺍﺧﺘﺼﺎﺻﻲ ﻳﮏ‬
‫ﻧﻮﻉ ﻏﻴﺮ ﻣﺠﺎﺯ ﺍﺳﺖ‪.‬‬

‫‪class varTestClass‬‬
‫{‬
‫!‪//Error : var cannot be used as field Data‬‬
‫;‪private var myNumber = 1‬‬

‫‪//Error : var cannot be used as return value‬‬


‫!‪//or parameter type‬‬
‫)‪public var myMethod(var x, var y‬‬
‫{‬
‫}‬
‫}‬

‫ﻣﺘﻐﻴﺮﻫﺎﻱ ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ ﻣﻲ ﺑﺎﻳﺴﺖ ﺩﺭ ﺯﻣﺎﻥ ﺗﻌﺮﻳﻒ ﻣﻘﺪﺍﺭ ﺩﻫﻲ ﺷﻮﻧﺪ ﺗﺎ ﻧﻮﻉ ﺁﻧﻬﺎ ﻣﺸﺨﺺ ﮔﺮﺩﺩ ﻭ ﺩﺭ ﺻﻮﺭﺕ ﺭﻫﺎ‬
‫ﺷﺪﻥ ﺑﺪﻭﻥ ﻣﻘﺪﺍﺭ ﺩﻫﻲ)ﺑﺎ ﻣﻘﺪﺍﺭ ‪ (null‬ﺩﺳﺘﻮﺭ ﻣﺬﮐﻮﺭ ﺑﺎ ﺧﻄﺎ ﺭﻭﺑﻪ ﺭﻭ ﺧﻮﺍﻫﺪ ﺷﺪ )ﻫﻤﺎﻧﻨﺪ ﻗﻮﺍﻧﻴﻦ ﺗﻌﺮﻳﻒ ﻳﮏ ﻣﺘﻐﻴﺮ ﺍﺯ ﻧﻮﻉ‬
‫‪.(const‬‬

‫!‪//error: must assign value‬‬


‫;‪var myNumber‬‬

‫!‪//error: must assign value at exact time of declaration‬‬


‫;‪var myWord‬‬
‫;"‪myWord= "Hello LINQ‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 9‬ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫ﺑﺮﺍﻱ ﺗﮑﻤﻴﻞ ﻣﺜﺎﻝ ﻗﺒﻞ ﺗﻮﺟﻪ ﮐﻨﻴﺪ ﮐﻪ ﺍﻣﮑﺎﻥ ﺗﻌﺮﻳﻒ ﻳﮏ ﻣﺘﻐﻴﺮ ﻣﺤﻠﻲ ﺑﺎ ﻧﻮﻉ ﺑﻨﺪﻱ ﺿﻤﻨﻲ ‪ nullable‬ﺑﺎ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ‬
‫ﺗﻮﮐﻦ ? ﻭﺟﻮﺩ ﻧﺪﺍﺭﺩ‪.‬‬

‫‪//can't define nullable implicit variable,‬‬


‫‪//as implicit variables can never be initially assigned‬‬
‫!‪//null to begin with‬‬

‫;‪var? myNumber = 1‬‬


‫;‪var? noValue = null‬‬

‫ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ‪Extension Methods -‬‬

‫ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺍﻣﮑﺎﻥ ﺑﻪ ﺩﺳﺖ ﺁﻭﺭﺩﻥ ﮐﺎﺭﺍﻳﻲ ﺟﺪﻳﺪ ﺭﺍ ﺑﺪﻭﻥ ﻧﻴﺎﺯ ﺑﻪ ﺍﺻﻼﺡ ﻣﺴﺘﻘﻴﻢ ﻧﻮﻉ ﻣﻮﺭﺩ ﺗﻮﺳﻌﻪ ﻭ ﻳﺎ ﺍﻧﻮﺍﻉ ﮐﺎﻣﭙﺎﻳﻞ‬
‫ﺷﺪﻩ ﻣﻮﺟﻮﺩ )ﮐﻼﺱ ﻫﺎ ‪ struct ،‬ﻫﺎ ﻭ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻫﺎﻱ ﺍﻳﻨﺘﺮﻓﻴﺲ( ﻭ ﻫﻤﭽﻨﻴﻦ ﺍﻧﻮﺍﻉ ﺩﺭ ﺣﺎﻝ ﮐﺎﻣﭙﺎﻳﻞ ﮐﻨﻮﻧﻲ ﺭﺍ ﺑﻮﺟﻮﺩ‬
‫ﻣﻲ ﺁﻭﺭﺩ )ﺑﻪ ﺩﻟﻴﻞ ﺩﺭ ﺩﺳﺘﺮﺱ ﻧﺒﻮﺩﻥ ﮐﺪ ﻭ ﻳﺎ ﺍﺟﺎﺯﻩ ﻧﺪﺍﺩﻥ ﮐﻼﺱ ﺑﺮﺍﻱ ﺍﺭﺙ ﺑﺮﻱ( ‪ .‬ﺍﻳﻦ ﺗﮑﻨﻴﮏ ﺑﺮﺍﻱ ﺗﺰﺭﻳﻖ ﮐﺎﺭﺍﻳﻲ ﺟﺪﻳﺪ‬
‫ﺑﻪ ﺍﻧﻮﺍﻋﻲ ﮐﻪ ﮐﺪ ﭘﺎﻳﻪ ﺁﻧﻬﺎ ﻭﺟﻮﺩ ﻧﺪﺍﺭﺩ ‪،‬ﺑﺴﻴﺎﺭ ﺳﻮﺩﻣﻨﺪ ﺧﻮﺍﻫﺪ ﺑﻮﺩ ﻭ ﻗﺎﺑﻠﻴﺖ ﺍﺻﻠﻲ ﭘﺮﺱ ﻭ ﺟﻮ ﻟﻴﻨﮏ ﺗﻮﺳﻂ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺑﻪ‬
‫ﺩﺳﺖ ﺁﻣﺪﻩ ﺍﺳﺖ‪.‬‬
‫ﺩﺭ ﺗﻌﺮﻳﻒ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺍﻭﻟﻴﻦ ﻣﺤﺪﻭﺩﻳﺘﻲ ﮐﻪ ﺑﺎ ﺁﻥ ﺭﻭﺑﻪ ﺭﻭ ﻣﻲ ﺷﻮﻳﻢ ﺍﻱﻥ ﺍ ﺳﺖ ﮐﻪ ﺁﻧﻬﺎ ﺑﺎﻳﺪ ﺩﺭﻭﻥ ﻳﮏ ﮐﻼﺱ ‪static‬‬
‫ﺗﻌﺮﻳﻒ ﺷﻮﻧﺪ‪ ،‬ﺑﻨﺎﺑﺮﺍﻳﻦ ﻫﺮ ﺗﺎﺑﻊ ﺗﻮﺳﻌﻪ ﻣﻲ ﺑﺎﻳﺴﺖ ﺑﺎ ﮐﻠﻤﻪ ﮐﻠﻴﺪﻱ ‪ static‬ﺗﻌﺮﻱﻑ ﺷﻮﺩ ﺩﻭﻣﻴﻦ ﻣﺤﺪﻭﺩﻳﺖ ﺍﻳﻦ ﺍﺳﺖ ﮐﻪ ﻣﺎ‬
‫ﺑﺮﺍﻱ ﺍﻋﻼﻡ ﺍﻳﻦ ﺗﺎﺑﻊ ﺑﻪ ﻋﻨﻮﺍﻥ ﺗﺎﺑﻊ ﺗﻮﺳﻌﻪ ﺑﻪ ﮐﺎﻣﭙﺎﻳﻠﺮ ﻣﻲ ﺑﺎﻳﺴﺖ ﺑﺎ ﻳﮏ ﮐﻠﻤﻪ ﮐﻠﻴﺪﻱ ‪ this‬ﺩﺭ ﺍﻭﻟﻴﻦ )ﻭ ﻓﻘﻂ ﺍﻭﻟﻴﻦ (‬
‫ﭘﺎﺭﺍﻣﺘﺮ ﻭﺭﻭﺩﻱ ﺗﺎﺑﻊ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﻢ‪.‬‬

‫ﻧﮕﺎﺗﻲ ﮐﻪ ﺑﺎﻳﺪ ﺩﺭ ﻫﻨﮕﺎﻡ ﺗﻌﺮﻳﻒ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺑﺎﻳﺪ ﺑﻪ ﺁﻧﻬﺎ ﺗﻮﺟﻪ ﮐﻨﻴﺪ‪:‬‬

‫ﺍﮔﺮ ﻳﮏ ﺗﺎﺑﻊ ﺗﻮﺳﻌﻪ ﺗﻌﺮﻳﻒ ﮐﺮﺩﻩ ﺍﻳﺪ ﻭﻟﻲ ﻳﮏ ﺗﻮﺳﻌﻪ ﺩﺍﺧﻠﻲ ﺑﺎ ﺍﻟﮕﻮﻳﻲ ﻣﺸﺎﺑﻪ )ﻧﻪ ﺍﻟﺒﺘﻪ ﻳﮑﺴﺎﻥ( ﻭﺟﻮﺩ‬
‫ﺩﺍﺷﺖ¡ ﺍﻭﻟﻮﻳﺖ ﻓﺮﺍﺧﻮﺍﻧﻲ ﺑﺎ ﺗﻮﺳﻌﻪ ﺩﺍﺧﻠﻲ ﺍﺳﺖ‪.‬‬
‫ﺧﺼﻮﺻﻴﺎﺕ‪ ،‬ﺭﻭﻳﺪﺍﺩﻫﺎ ﻭ ﻋﻤﻠﮕﺮﻫﺎ ﻗﺎﺑﻞ ﺗﻮﺳﻌﻪ ﻧﻴﺴﺘﻨﺪ ﻭﻟﻲ ﻣﻄﺮﺡ ﺷﺪﻩ ﺍﻧﺪ ﻭ ﺍﻣﻴﺪ ﺍﺳﺖ ﺩﺭ ﻧﺴﺨﻪ ﻫﺎﻱ‬
‫ﺑﻌﺪﻱ ‪ C#‬ﺍﻳﻦ ﻗﺎﺑﻠﻴﺖ ﻫﺎ ﻧﻴﺰ ﺍﻓﺰﻭﺩﻩ ﺷﻮﻧﺪ‪.‬‬
‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ ‪| LINQ‬ﺻﻔﺤﻪ‪10‬‬ ‫‪www.AliAghdam.ir‬‬

‫ﺑﻴﺸﺘﺮ ﺑﺪﺍﻧﻴﻢ‬
‫ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺫﺍﺗﺎ ﺗﻮﺍﺑﻊ ﺍﻳﺴﺘﺎﻱ ﻣﻌﻤﻮﻟﻲ ﻫﺴﺘﻨﺪ ﮐﻪ ﻣﻲ ﺗﻮﺍﻧﻨﺪ ﺩﺭ ﻳﮏ ﻧﻤﻮﻧﻪ ﺍﺯ ﻧﻮﻉ ﺗﻮﺳﻌﻪ ﻳﺎﻓﺘﻪ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ‬
‫ﮔﻴﺮﻧﺪ ﮐﻪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻗﻮﺍﻋﺪ ﻧﺤﻮﻱ ﺗﻮﺍﺑﻊ ﺍﻳﺴﺘﺎ ﻧﻤﻲ ﺗﻮﺍﻧﻨﺪ ﺑﻪ ﺍﻋﻀﺎﻱ )ﻓﻴﻠﺪ ﻭ ﻳﺎ ﺗﻮﺍﺑﻊ( ﺩﻳﮕﺮ ﻧﻮﻉ ﺗﻮﺳﻌﻪ ﻳﺎﻓﺘﻪ ‪ ،‬ﺩﺳﺘﺮﺳﻲ‬
‫ﭘﻴﺪﺍ ﮐﻨﻨﺪ ﮐﻪ ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﺍﻳﻦ ﻣﺴﻌﻠﻪ ﺗﻮﺳﻌﻪ ﺩﺍﺩﻥ ﺑﺎ ﺑﻪ ﺍﺭﺙ ﺑﺮﺩﻥ ﺑﻪ ﮐﻠﻲ ﺗﻔﺎﻭﺕ ﺩﺍﺭﺩ ﻭ ﺷﻤﺎ ﻧﻤﻲ ﺗﻮﺍﻧﻴﺪ ﻳﮏ ﻓﻴﻠﺪ ﻳﮏ‬
‫ﮐﻼﺱ ﺭﺍ ﺗﻮﺳﻂ ﺗﺎﺑﻊ ﺗﻮﺳﻌﻪ ﺧﻮﺩ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﺩﻫﻴﺪ‪.‬‬

‫ﺗﻌﺮﻳﻒ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ‬


‫ﻫﻤﺎﻧﻄﻮﺭ ﮐﻪ ﺍﺷﺎﺭﻩ ﺷﺪ ﺩﺭ ﺗﻌﺮﻳﻒ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺍﻭﻟﻴﻦ ﭘﺎﺭﺍﻣﺘﺮ ﻭﺭﻭﺩﻱ ﺗﺎﺑﻊ ﺑﺎ ﮐﻠﻤﻪ ﮐﻠﻴﺪﻱ ‪ this‬ﺷﺮﻭﻉ ﻣﻲ ﺷﻮﺩ ﻭ ﻧﺎﻡ‬
‫ﮐﻼﺱ ﻣﻮﺭﺩ ﻧﻈﺮ ﺑﺮﺍﻱ ﺗﻮﺳﻌﻪ ﻧﻴﺰ ﻗﻴﺪ ﮔﺮﺩﺩ ﻭ ﺗﺎﺑﻊ ﻣﻲ ﺑﺎﻳﺴﺖ ﺍﺯ ﻧﻮﻉ ‪ static‬ﺑﺎﺷﺪ‪ .‬ﻣﺜﺎﻝ ﺯﻳﺮ ﻧﺤﻮﻩ ﺗﻌﺮﻳﻒ ﻳﮏ ﺗﺎﺑﻊ‬
‫ﺗﻮﺳﻌﻪ ﺭﺍ ﻧﺸﺎﻥ ﻣﻲ ﺩﻫﺪ ﺑﻪ ﻗﺴﻤﺖ ﻫﺎﻱ ﺿﺨﻴﻢ ﺩﻗﺖ ﮐﻨﻴﺪ‪.‬‬

‫‪static class MyExtensionMethodes‬‬


‫{‬
‫‪///‬‬
‫‪/// Returns a converted null and space to an empty string.‬‬
‫‪///‬‬
‫) ‪public static string ConvertNullToEmptyString(this string strInput‬‬
‫{‬
‫‪return ( String.IsNullOrWhiteSpace(strInput) ? string.Empty : strInput‬‬
‫;)‬
‫}‬
‫}‬

‫ﺑﺮﺭﺳﻲ ﻧﺤﻮﻩ ﻋﻤﻠﮑﺮﺩ ﻣﺜﺎﻝ ﺑﺎﻻ ﺑﻪ ﻋﻬﺪﻩ ﺧﻮﺩﺗﺎﻥ!‬

‫ﻧﮑﺘﻪ‬
‫ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺗﻤﺎﻣﻲ ﻗﺎﺑﻠﻴﺖ ﻫﺎﻱ ﺗﻮﺍﺑﻊ ﺍﻳﺴﺘﺎﻱ ﻣﻌﻤﻮﻝ ﺭﺍ ﺩﺍﺭﺍ ﻣﻲ ﺑﺎﺷﻨﺪ ﻳﻌﻨﻲ ﻣﻲ ﺗﻮﺍﻥ ﺁﻧﻬﺎ ﺭﺍ ﺑﻮﺳﻴﻠﻪ ﺗﻮﺍﺑﻊ ﺍﻳﺴﺘﺎ ﻭ ﻳﺎ‬
‫ﻧﻤﻮﻧﻪ ﺳﺎﺯﻱ ﺷﺪﻩ ﻓﺮﺍﺧﻮﺍﻧﻲ ﻧﻤﻮﺩ‪.‬‬

‫ﻓﺮﺍﺧﻮﺍﻧﻲ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺩﺭ ﺳﻄﺢ ﻧﻤﻮﻧﻪ ﺍﻱ‬


‫ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺗﻨﻬﺎ ﮐﺎﻓﻲ ﺍﺳﺖ ﮐﻪ ﺗﺎﺑﻊ ﺗﻮﺳﻌﻪ ﺩﺭ ﻓﻀﺎﻱ ﻧﺎﻡ ﺟﺎﺭﻱ ﺑﺎﺷﺪ ﻭ ﻳﺎ ﺍﻳﻨﮑﻪ ﻳﮏ ﺍﺭﺟﺎﻉ ﺑﻪ ﺁﻥ‬
‫ﻓﻀﺎﻱ ﻧﺎﻡ ﺩﺭ ﻓﻀﺎﻱ ﻧﺎﻡ ﺟﺎﺭﻱ ﻭﺟﻮﺩ ﺩﺍﺷﺘﻪ ﺑﺎﺷﺪ‪.‬‬

‫ﺑﻪ ﻃﻮﺭ ﻣﺜﺎﻝ ﺍﺯ ﺗﺎﺑﻊ ﺗﻮﺳﻌﻪ ﻣﺜﺎﻝ ﺑﺎﻻ ﺩﺭ ﺍﻳﻦ ﻣﺜﺎﻝ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﮐﻨﻴﻢ‪.‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 11‬ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫;‪string strTest = null‬‬


‫;)(‪strTest = strTest.ConvertNullToEmptyString‬‬

‫ﻓﺮﺍﺧﻮﺍﻧﻲ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺩﺭ ﺳﻄﺢ ﺍﻳﺴﺘﺎ‬


‫ﻫﻤﺎﻧﻄﻮﺭ ﮐﻪ ﻗﺒﻼ ﺍﺷﺎﺭﺍﺗﻲ ﺷﺪ ﻣﻲ ﺗﻮﺍﻥ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺭﺍ ﺑﻪ ﺻﻮﺭﺕ ﺗﻮﺍﺑﻊ ﺍﻳﺴﺘﺎﻱ ﻣﻌﻤﻮﻟﻲ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﺩﺍﺩ ﮐﻪ ﺍﻟﺒﺘﻪ‬
‫ﺑﻌﺪ ﺍﺯ ﺗﺒﺪﻳﻞ ﺷﺪﻥ ﮐﺪ ﺑﻪ ﮐﺪ ‪ IL‬ﮐﺪ ﻗﺒﻠﻲ ﺑﺎ ﮐﺪ ﺟﺪﻳﺪ ﮐﻪ ﻫﻤﺎﻥ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻌﻤﻮﻝ ﺍﺯ ﺗﺎﺑﻊ ﺍﻳﺴﺘﺎ ﺍﺳﺖ ‪ ،‬ﺟﺎﻳﮕﺰﻳﻦ ﻣﻲ ﮔﺮﺩﺩ‪.‬‬

‫;‪string strTest = null‬‬


‫;)‪strTest = MyExtensionMethodes.ConvertNullToEmptyString(strTest‬‬

‫ﺍﺳﺘﻔﺎﺩﻩ ‪ Intelisense‬ﺍﺯ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ‬


‫ﺯﻣﺎﻧﻲ ﮐﻪ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺍﻱ ﺭﺍ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﻴﺪ ﻭ ﻗﺼﺪ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺁﻧﻬﺎ ﺭﺍ ﺩﺍﺭﻳﺪ ‪،‬ﻣﮑﺎﻧﻴﺰﻡ ‪ Intelisense‬ﻭﻳﮋﻭﺍﻝ ﺍﺳﺘﻮﺩﻳﻮ‬
‫ﺁﻧﻬﺎ ﺭﺍ ﺗﺸﺨﻴﺺ ﻣﻲ ﺩﻫﺪ ﻭ ﻧﻤﺎﻳﺶ ﻣﻲ ﺩﻫﺪ ﺗﺎ ﻧﻴﺎﺯﻱ ﺑﻪ ﺑﻪ ﺧﺎﻃﺮ ﺳﭙﺎﺭﻱ ﺁﻧﻬﺎ ﺭﺍ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ‪ Intelisense .‬ﺗﻮﺍﺑﻊ‬
‫ﺗﻮﺳﻌﻪ ﺭﺍ ﺑﻪ ﻭﺳﻴﻠﻪ ﻳﮏ ﺷﮑﻠﮏ ﺑﺎ ﻳﮏ ﻓﻠﺶ ﺭﻭ ﺑﻪ ﭘﺎﻳﻴﻦ ﺑﻪ ﻧﻤﺎﻳﺶ ﻣﻲ ﮔﺬﺍﺭﺩ‪.‬‬

‫ﻫﻤﺎﻧﻄﻮﺭ ﮐﻪ ﻣﺸﺎﻫﺪﻩ ﻣﻲ ﮐﻨﻴﺪ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺩﻳﮕﺮﻱ ﻧﻴﺰ ﻭﺟﻮﺩ ﺩﺍﺭﻧﺪ ﮐﻪ ﺍﮐﺜﺮﻳﺖ ﺁﻧﻬﺎ ﻧﻴﺰ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ‪ LINQ‬ﻫﺴﺘﻨﺪ‪.‬‬
‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ ‪| LINQ‬ﺻﻔﺤﻪ‪12‬‬ ‫‪www.AliAghdam.ir‬‬

‫ﺗﻮﺳﻌﻪ ﺭﺍﺑﻂ ﻫﺎ ﺑﻮﺳﻴﻠﻪ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ‬


‫ﺩﺭ ﺍﺑﺘﺪﺍﻱ ﺗﻮﺿﻴﺤﺎﺕ ﺑﻴﺎﻥ ﻧﻤﻮﺩﻡ ﮐﻪ ﺍﻣﮑﺎﻥ ﺗﻮﺳﻌﻪ ﺭﺍﺑﻂ‪ ϭ‬ﻫﺎ ﻧﻴﺰ ﻭﺟﻮﺩ ﺩﺍﺭﺩ ﻭﻟﻲ ﻣﺎﻫﻴﺖ ﺍﻧﺠﺎﻡ ﺍﻳﻦ ﻋﻤﻞ ﺑﺎ ﺗﻮﺳﻌﻪ ﻳﮏ‬
‫ﮐﻼﺱ ﺗﻔﺎﻭﺕ ﺩﺍﺭﺩ‪ .‬ﺍﻳﻦ ﻋﻤﻞ ﺭﺍ ﺑﻪ ﺻﻮﺭﺕ ﻗﺪﻡ ﺑﻪ ﻗﺪﻡ ﺍﻧﺠﺎﻡ ﻣﻲ ﺩﻫﻴﻢ ﺗﺎ ﻣﺮﺍﺣﻞ ﺁﻥ ﺭﺍ ﺑﻪ ﺧﻮﺑﻲ ﺩﺭﮎ ﮐﻨﻴﺪ‪.‬‬

‫ﺑﺮﺍﻱ ﺷﺮﻭﻉ ﻳﮏ ﺭﺍﺑﻂ ﺟﺪﻳﺪ ﺑﻪ ﻧﺎﻡ ‪ ILocatable‬ﺍﻳﺠﺎﺩ ﮐﻨﻴﺪ ﻭ ﺳﭙﺲ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺯﻳﺮ ﺭﺍ ﺑﺮﺍﻱ ﺁﻥ ﺗﻌﺮﻳﻒ ﮐﻨﻴﺪ‪.‬‬

‫‪// Define a normal CLR interface in C#.‬‬


‫‪public interface ILocatable‬‬
‫{‬
‫} ;‪int Longitude { get; set‬‬
‫} ;‪int Latitude { get; set‬‬
‫}‬

‫ﺣﺎﻝ ﺍﻳﻦ ﺭﺍﺑﻂ ﺭﺍ ﺑﻪ ﻳﮏ ﮐﻼﺱ ﺍﻋﻤﺎﻝ ﮐﻨﻴﺪ‬

‫‪// Implementation of ILocatable.‬‬


‫‪public class Car : ILocatable‬‬
‫{‬
‫} ;‪public int Longitude { get; set‬‬
‫} ;‪public int Latitude { get; set‬‬
‫}‬

‫ﺭﺍﺑﻂ ‪ ILocatable‬ﺩﺍﺭﺍﻱ ﺩﻭ ﻣﺘﺪ ﺍﺳﺖ ﮐﻪ ﺩﺭ ﮐﻼﺱ ‪ Car‬ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺷﺪﻩ ﺍﺳﺖ‪ .‬ﺑﺎﻓﺮﺽ ﺍﻳﻨﮑﻪ ﻣﺎ ﺑﻪ ﮐﺪ ﺭﺍﺑﻂ‬
‫‪ ILocatable‬ﺩﺳﺘﺮﺳﻲ ﻧﺪﺍﺭﻳﻢ ﻭﻳﺎ ﻧﻤﻲ ﺧﻮﺍﻫﻴﻢ ﺩﺭ ﺁﻥ ﺗﻐﻴﻴﺮﻱ ﺑﺪﻫﻴﻢ ﻭ ﻣﻲ ﺧﻮﺍﻫﻴﻢ ﺁﻥ ﺭﺍ ﺗﻮﺳﻌﻪ ﺩﻫﻴﻢ ﮐﻪ ﺑﺮﺍﻱ ﺍﻳﻦ‬
‫ﻋﻤﻞ ﺭﺍ ﻧﻤﻲ ﺗﻮﺍﻥ ﺑﻪ ﺷﮑﻞ ﻣﻌﻤﻮﻝ ﺍﻧﺠﺎﻡ ﺩﻫﻴﻢ ‪.‬‬

‫ﺑﺮﺍﻱ ﺍﻳﻨﮑﻪ ﻳﮏ ﺭﺍﺑﻂ ﺭﺍ ﺗﻮﺳﻌﻪ ﺩﻫﻴﻢ ﻣﻲ ﺑﺎﻳﺴﺖ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺁﻥ ﺗﻮﺍﺑﻊ ﺭﺍ ﻧﻴﺰ ﻣﻬﻴﺎ ﮐﻨﻴﺪ ﻭ ﺍﻳﻦ ﺭﺍ ﺑﻪ ﺍﻳﻦ ﺻﻮﺭﺕ ﻓﺮﺽ‬
‫ﮐﻨﻴﺪ ﮐﻪ ﮐﻼﺱ ﻫﺎﻱ ﮐﻪ ﺍﻳﻦ ﺭﺍﺑﻂ ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻣﻲ ﮐﻨﻨﺪ ﺷﺎﻣﻞ ﻳﮏ ﻣﺘﺪ ﺑﺎ ﺍﻳﻦ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻫﺴﺘﻨﺪ‪ .‬ﺍﻳﻦ ﻋﻤﻞ ﺭﺍ ﺩﺭ‬
‫ﻣﺜﺎﻝ ﺯﻳﺮ ﻣﺸﺎﻫﺪﻩ ﮐﻨﻴﺪ‪.‬‬

‫‪1‬‬
‫‪Interface‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 13‬ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫‪public static class LocatableExtensions‬‬


‫{‬
‫)‪public static void MoveNorth(this ILocatable locatable, int degrees‬‬
‫{‬
‫‪// ...‬‬
‫}‬

‫)‪public static void MoveWest(this ILocatable locatable, int degrees‬‬


‫{‬
‫‪// ..‬‬
‫}‬
‫}‬

‫ﺣﺎﻝ ﺯﻣﺎﻧﻲ ﮐﻪ ﺍﺯ ﮐﻼﺳﻲ ﮐﻪ ﺭﺍﺑﻂ ‪ ILocatable‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩﻩ ﻧﻤﻮﻧﻪ ﺳﺎﺯﻱ ﺷﻮﺩ‪ ،‬ﺁﻥ ﮐﻼﺱ ﻣﻲ ﺗﻮﺍﻧﺪ ﺑﻪ‬
‫ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺩﺍﺩﻩ ﺷﺪﻩ ﺩﺳﺘﺮﺳﻲ ﭘﻴﺪﺍ ﮐﻨﺪ‪.‬‬

‫;)(‪Car car = new Car‬‬

‫;)‪car.MoveNorth(23‬‬

‫;)‪car.MoveWest(23‬‬

‫ﺑﻴﺸﺘﺮ ﺑﺪﺍﻧﻴﻢ‬
‫ﺑﺮﺍﻱ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺑﻬﺘﺮ ﺍﺳﺖ ﮐﺘﺎﺑﺨﺎﻧﻪ ﺍﻱ ﺍﺯ ﺁﻥ ﺩﺭ ﺩﺳﺘﻪ ﺑﻨﺪﻱ ﻫﺎﻱ ﻣﺨﺘﻠﻒ ﺗﻬﻴﻪ ﮐﻨﻴﺪ ﺗﺎ ﺍﺯ ﺁﻧﻬﺎ ﺑﺘﻮﺍﻧﻴﺪ‬
‫ﺩﺭ ﭘﺮﻭﮊﻩ ﻫﺎﻱ ﻣﺨﺘﻠﻒ ﺑﻪ ﺭﺍﺣﺘﻲ ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ ﻫﻤﭽﻨﻴﻦ ﻳﮏ ﭘﺎﻳﮕﺎﻩ ﺍﻳﻨﺘﺮﻧﺘﻲ ﻭﺟﻮﺩ ﺩﺍﺭﺩ ﮐﻪ ﺩﺭ ﺁﻥ ﮐﺎﺭﺑﺮﺍﻥ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ‬
‫ﺧﻮﺩ ﺭﺍ ﺑﻪ ﺍﺷﺘﺮﺍﮎ ﻣﻲ ﮔﺬﺍﺭﻧﺪ ﮐﻪ ﻣﻲ ﺗﻮﺍﻧﺪ ﺑﻪ ﻋﻨﻮﺍﻥ ﻳﮏ ﭘﺎﻳﮕﺎﻩ ﻋﻈﻴﻢ ﺍﻃﻼﻋﺎﺗﻲ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﮔﻴﺮﺩ‪.‬‬
‫ﺍﻳﻦ ﭘﺎﻳﮕﺎﻩ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺭﺍ ﺑﺮﺍﻱ ﺳﻪ ﺯﺑﺎﻥ ‪ F#¡ C#‬ﻭ ﻭﻳﮋﻭﺍﻝ ﺑﻴﺴﻴﮏ ﻭ ﺩﺭ ﺩﺳﺘﻪ ﺑﻨﺪﻱ ﻫﺎﻱ ﺑﺴﻴﺎﺭ ﺯﻳﺎﺩ ﺍﺭﺍﺋﻪ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﺁﺩﺭﺱ ﺍﻳﻦ ﭘﺎﻳﮕﺎﻩ ‪www.ExtensionMethod.net :‬‬


‫‪U‬‬ ‫‪U‬‬
‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ ‪| LINQ‬ﺻﻔﺤﻪ‪14‬‬ ‫‪www.AliAghdam.ir‬‬

‫ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ‪Lambda Expressions -‬‬

‫ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ﺗﻮﺍﺑﻊ ﻧﺎﺷﻨﺎﺧﺘﻪ ﺍﻱ ﻫﺴﺘﻨﺪ ﮐﻪ ﻣﻲ ﺗﻮﺍﻧﻨﺪ ﺷﺎﻣﻞ ﻋﺒﺎﺭﺍﺕ ﻭ ﻗﻄﻌﺎﺕ ﮐﺪ ﺑﺎﺷﻨﺪ ﮐﻪ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ ﺁﻧﻬﺎ ﺑﺮﺍﻱ‬
‫ﺳﺎﺧﺖ ﺩﺭﺧﺖ ﻫﺎﻱ ﻋﺒﺎﺭﺕ ‪ Ϯ‬ﻭ ‪ Delegate‬ﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‪ .‬ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ﺍﻳﻦ ﺍﻣﮑﺎﻥ ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﻨﺪ ﮐﻪ ﺗﻮﺍﺑﻌﻲ‬
‫ﺍﻳﺠﺎﺩ ﻧﻤﻮﺩﻩ ﻭ ﺁﻧﻬﺎ ﺭﺍ ﺑﻪ ﻋﻨﻮﺍﻥ ﺁﺭﮔﻮﻣﺎﻥ ﺑﻪ ﻣﺘﺪﻫﺎ ﺍﺭﺳﺎﻝ ﮐﺮﺩ‪.‬‬
‫ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ﻳﮏ ﺗﺎﺑﻊ ﺭﺍ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻭ ﺗﻮﺍﻧﺎﻳﻲ ﺗﻌﺮﻳﻒ ﺗﻮﺍﺑﻊ ‪ Inline‬ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﻨﺪ ‪.‬ﺗﻮﺟﻪ ﮐﻨﻴﺪ ﮐﻪ‬
‫ﻧﻮﺷﺘﻦ ﻋﺒﺎﺭﺍﺕ ‪ Lambda‬ﻫﻴﭻ ﭘﻴﭽﻴﺪﮔﻲ ﻧﺪﺍﺭﺩ ﻭ ﺧﻮﺍﻫﻴﺪ ﻓﻬﻤﻴﺪ ﮐﻪ ﺑﺴﻴﺎﺭ ﻫﻢ ﺩﺭ ‪ LINQ‬ﻭ ‪ Delegate‬ﻫﺎ ﭘﺮ ﮐﺎﺭﺑﺮﺩ‬
‫ﻫﺴﺘﻨﺪ‪.‬‬

‫ﺗﻌﺮﻳﻒ ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ‬

‫ﺑﺮﺍﻱ ﺗﻌﺮﻳﻒ ﻳﮏ ﺗﺎﺑﻊ ﻣﻌﻤﻮﻝ ﻣﻲ ﺑﺎﻳﺴﺖ ﭘﻨﺞ ﻗﺴﻤﺖ ﺭﺍ ﺑﻪ ﺻﻮﺭﺕ ﺻﺮﻳﺢ ﺗﻌﺮﻳﻒ ﮎﺭﺩ ‪:‬‬

‫ﻧﻮﻉ ﺩﺳﺘﺮﺳﻲ ﺑﻪ ﺗﺎﺑﻊ‬ ‫‪.۱‬‬


‫ﻧﻮﻉ ﺧﺮﻭﺟﻲ ﺗﺎﺑﻊ‬ ‫‪.۲‬‬
‫ﻧﺎﻡ ﺗﺎﺑﻊ‬ ‫‪.۳‬‬
‫ﻟﻴﺴﺖ ﭘﺎﺭﺍﻣﺘﺮ ﻫﺎﻱ ﻭﺭﻭﺩﻱ‬ ‫‪.۴‬‬
‫ﺑﺪﻧﻪ ﺗﺎﺑﻊ‬ ‫‪.۵‬‬

‫ﻭﻟﻲ ﺑﺮﺍﻱ ﺗﻌﺮﻳﻒ ﻋﺒﺎﺭﺕ ﻻﻣﺒﺪﺍ ﻓﻖﻁ ﺩﻭ ﻣﺮﺣﻠﻪ ﺍﺯ ﻣﺮﺍﺣﻞ ﺗﻌﺮﻳﻒ ﺗﺎﺑﻊ ﺭﺍ ﺍﻧﺠﺎﻡ ﻣﻲ ﺩﻫﻴﻢ‪.‬‬

‫‪ .۱‬ﻟﻴﺴﺖ ﭘﺎﺭﺍﻣﺘﺮ ﻫﺎ‬


‫‪ .۲‬ﺑﺪﻧﻪ ﺗﺎﺑﻊ‬

‫‪2‬‬
‫‪Expression Tree‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 15‬ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫ﻗﺴﻤﺖ ﺍﻭﻝ ﻋﺒﺎﺭﺕ ﻻﻣﺒﺪﺍ ) ﻋﺒﺎﺭﺕ ﺩﺍﺧﻞ ﭘﺮﺍﻧﺘﺰ( ﺑﻪ ﻋﻨﻮﺍﻥ ﺁﺭﮔﻮﻣﺎﻥ ﻫﺎﻱ ﺗﺎﺑﻊ ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﺍﮔﺮ ﻋﺒﺎﺭﺕ‬
‫ﻻﻣﺒﺪﺍﻱ ﻣﻮﺭﺩ ﻧﻈﺮ ﺷﻤﺎ ﻓﺎﻗﺪ ﺁﺭﮔﻮﻣﺎﻥ ﺑﺎﺷﺪ ﻣﻲ ﺗﻮﺍﻧﻴﺪ ﺍﺯ ﺍﻳﻦ ﻗﺴﻤﺖ ﺻﺮﻑ ﻧﻈﺮ ﮐﻨﻴﺪ‪.‬‬
‫ﻗﺴﻤﺖ ﺩﻭﻡ ﻳﻌﻨﻲ>= ﺑﻪ ﮐﺎﻣﭙﺎﻳﻠﺮ ﺍﻋﻼﻡ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﺍﻳﻦ ﻋﺒﺎﺭﺕ ﻳﮏ ﻋﺒﺎﺭﺕ ﻻﻣﺒﺪﺍ ﺍﺳﺖ ﻭ ﻗﺴﻤﺖ ﺳﻮﻡ ﺑﺪﻧﻪ ﺗﺎﺑﻊ ﺭﺍ ﻧﺸﺎﻥ‬
‫ﻣﻲ ﺩﻫﺪ ﮐﻪ ﺩﺭ ﺍﻳﻦ ﻋﺒﺎﺭﺕ ﺑﺪﻧﻪ ﺳﺎﺩﻩ ﺍﺳﺖ ﻭﻟﻲ ﺍﮔﺮ ﺷﻤﺎ ﺧﻮﺍﺳﺘﻴﺪ ﺑﺪﻧﻪ ﺑﻴﺸﺘﺮ ﺭﺍ ﺩﺭ ﻋﺒﺎﺭﺕ ﺧﻮﺩ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﻣﻲ ﺑﺎﻳﺴﺖ‬
‫ﺩﺳﺘﻮﺭﺍﺕ ﺩﺭﻭﻥ ‪ brase‬ﻗﺮﺍﺭ ﺩﻫﻴﺪ ﻭ ﺁﻧﻬﺎ ﺭﺍ ﺑﺎ ﺳﻤﻲ ﮐﻮﻟﻮﻥ ﺟﺪﺍ ﮐﻨﻴﺪ‪.‬‬

‫ﻣﺜﺎﻝ ﺯﻳﺮ ﻧﺤﻮﻩ ﺗﻌﺮﻳﻒ ﻳﮏ ﻋﺒﺎﺭﺕ ﻻﻣﺒﺪﺍ ﺭﺍ ﻧﺸﺎﻥ ﻣﻲ ﺩﻫﺪ‪:‬‬


‫;‪(int x) => x + 1‬‬

‫ﻋﺒﺎﺭﺕ ﺑﺎﻻ ﻣﻌﺎﺩﻝ ﻋﺒﺎﺭﺕ ﺯﻳﺮ ﺍﺳﺖ ‪:‬‬

‫)‪int func(int x‬‬


‫{‬
‫;‪return x + 1‬‬
‫}‬

‫ﺑﻴﺸﺘﺮ ﺑﺪﺍﻧﻴﻢ‬
‫ﺩﺭ ﻫﻨﮕﺎﻡ ﮐﺎﻣﭙﺎﻳﻞ ﺷﺪﻥ ﻋﺒﺎﺭﺕ ﻻﻣﺒﺪﺍ ‪،‬ﮐﺎﻣﭙﺎﻳﻠﺮ ﺁﻥ ﻋﺒﺎﺭﺕ ﺭﺍ ﺑﻪ ﻋﻨﻮﺍﻥ ‪ Delegate‬ﺩﺭ ﻧﻈﺮ ﻣﻲ ﮔﻴﺮﺩ ﻭ ﭘﻴﺎﺩﻩ‬
‫ﺳﺎﺯﻱ ﺁﻥ ﺭﺍ ﺩﺭ ﮐﻼﺱ ﺟﺎﺭﻱ ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ ﻭ ﻧﻮﻉ ﺩﺳﺘﺮﺳﻲ ﺑﻪ ﺗﺎﺑﻊ ﻣﻮﺭﺩ ﻧﻈﺮ ﺧﺼﻮﺻﻲ ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﺩ‪ .‬ﺑﻪ ﺍﻳﻦ ﻫﺎ‬
‫ﺗﻮﺍﺑﻊ ﺑﻲ ﻧﺎﻡ ‪ ϯ‬ﺍﻃﻼﻕ ﻣﻲ ﮔﺮﺩﺩ ﭼﻮﻥ ﻧﺎﻡ ﺗﺎﺑﻊ ﺗﻮﺳﻂ ﮐﺎﻣﭙﺎﻳﻞ ﺍﻧﺘﺨﺎﺏ ﻣﻲ ﮔﺮﺩﺩ ﻭ ﻫﻴﭻ ﻗﺎﻧﻮﻥ ﻣﺸﺨﺼﻲ ﺑﺮﺍﻱ ﺁﻥ ﻭﺟﻮﺩ‬
‫ﻧﺪﺍﺭﺩ ﻳﻌﻨﻲ ﺑﺎ ﭼﻨﺪ ﺑﺎﺭ ﮐﺎﻣﭙﺎﻳﻞ ﻳﮏ ﮐﺪ ‪ ،‬ﭼﻨﺪﻳﻦ ﻧﺎﻡ ﻣﺨﺘﻠﻒ ﺑﻪ ﺁﻥ ﻧﺴﺒﺖ ﺩﺍﺩﻩ ﻣﻲ ﺷﻮﺩ‪.‬‬
‫ﻧﺎﻡ ﺍﻳﻦ ﺗﺎﺑﻊ ﺑﺎ ﻋﻼﻣﺖ " < " ﺷﺮﻭﻉ ﻣﻲ ﺷﻮﺩ ﭼﻮﻥ ﺷﻤﺎ ﻫﻴﭻ ﻣﻮﻗﻊ ﻧﻤﻲ ﺗﻮﺍﻧﻴﺪ ﺍﺩﻋﺎ ﮐﻨﻴﺪ ﮐﻪ ﺗﺎﺑﻌﻲ ﻧﻮﺷﺘﻪ ﺍﻳﺪ ﮐﻪ ﺑﺎ ﺍﻳﻦ‬
‫ﻋﻼﻣﺖ ﺭﺍ ﺷﺮﻭﻉ ﻣﻲ ﺷﻮﺩ! ﭘﺲ ﮐﺎﻣﭙﺎﻳﻠﺮ ﺍﺯ ﺍﻳﻦ ﺭﺍﻩ ﺁﻧﻬﺎ ﺭﺍ ﺗﺸﺨﻴﺺ ﻣﻲ ﺩﻫﺪ ﻫﻤﭽﻨﻴﻦ ﮐﺎﻣﭙﺎﻳﻠﺮ ﻳﮏ ﺧﺼﻴﺼﻪ‬
‫‪ System.Runtime.CompilerServices.CompilerGeneratedAttribute‬ﻧﻴﺰ ﺑﻪ ﺗﺎﺑﻊ ﺍﺿﺎﻓﻪ ﻣﻲ ﮐﻨﺪ ﺗﺎ ﺩﭼﺎﺭ‬
‫ﺍﺷﺘﺒﺎﻩ ﻧﺸﻮﺩ‪.‬ﺑﻪ ﻋﺒﺎﺭﺕ ﺯﻳﺮ ﺩﻗﺖ ﮐﻨﻴﺪ‬
‫‪internal sealed class AClass‬‬
‫{‬
‫)(‪public static void CallbackWithoutNewingADelegateObject‬‬
‫{‬
‫;)‪ThreadPool.QueueUserWorkItem(obj => Console.WriteLine(obj), 5‬‬
‫}‬
‫}‬

‫ﻋﺒﺎﺭﺕ ﺑﺎﻻ ﺑﻌﺪ ﺍﺯ ﮐﺎﻣﭙﺎﻳﻞ ﺑﻪ ﮐﺪ ‪ ، IL‬ﺑﻪ ﻋﺒﺎﺭﺍﺕ ﺻﺨﻴﻢ ﺷﺪﻩ ﺩﻗﺖ ﮐﻨﻴﺪ‬
‫{ ‪internal sealed class AClass‬‬

‫‪// This private field is created to cache the delegate object.‬‬


‫‪// Pro: CallbackWithoutNewingADelegateObject will not create‬‬

‫‪3‬‬
‫‪anonymous function‬‬
‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ ‪| LINQ‬ﺻﻔﺤﻪ‪16‬‬ ‫‪www.AliAghdam.ir‬‬

‫‪// a new object each time it is called.‬‬


‫‪// Con: The cached object never gets garbage collected‬‬
‫]‪[CompilerGenerated‬‬
‫;‪private static WaitCallback <>9__CachedAnonymousMethodDelegate1‬‬

‫{ )(‪public static void CallbackWithoutNewingADelegateObject‬‬


‫{ )‪if (<>9__CachedAnonymousMethodDelegate1 == null‬‬
‫‪// First time called, create the delegate object and‬‬
‫‪cache it.‬‬
‫= ‪<>9__CachedAnonymousMethodDelegate1‬‬
‫‪new‬‬
‫)‪WaitCallback(<CallbackWithoutNewingADelegateObject>b__0‬‬
‫;‬
‫}‬

‫‪ThreadPool.QueueUserWorkItem(<>9__CachedAnonymousMethodDeleg‬‬
‫;)‪ate1, 5‬‬
‫}‬

‫]‪[CompilerGenerated‬‬
‫‪private static void‬‬
‫{ )‪<CallbackWithoutNewingADelegateObject>b__0(Object obj‬‬
‫;)‪Console.WriteLine(obj‬‬
‫}‬
‫}‬

‫ﺍﮔﺮ ﺩﻗﺖ ﮐﺮﺩﻩ ﺑﺎﺷﻴﺪ ﺩﺭ ﺍﺳﺘﻔﺎﺩﻩ ﻫﺎﻱ ﻣﻌﻤﻮﻝ ﻋﺒﺎﺭﺕ ﻻﻣﺒﺪﺍ ﻗﺼﺪ ﺩﺍﺭﺩ ﺗﺎ ﻳﮏ ﺳﻄﺢ ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﺭﺍ ﮐﻢ ﮐﻨﺪ ﻭ ﺧﻮﺩ‬
‫ﺍﻳﻦ ﻣﺴﺌﻮﻟﻴﺖ ﺭﺍ ﺑﻪ ﺩﻭﺵ ﺑﮑﺸﺪ )ﺍﻟﺒﺘﻪ ﮐﺎﻣﭙﺎﻳﻠﺮ(‪.‬‬

‫ﻋﺒﺎﺭﺍﺕ ﭘﺮﺱ ﻭ ﺟﻮ ‪Query Expresions -‬‬

‫ﺩﺭ ﻫﻨﮕﺎﻡ ﺗﻌﺎﻣﻞ ﺑﺎ ﭘﺎﻳﮕﺎﻩ ﻫﺎﻱ ﺩﺍﺩﻩ ﺩﺭ ﻭﺍﻗﻊ ﻣﺎ ﺍﺯ ﺩﻭ ﺯﺑﺎﻥ ﺑﺮﺍﻱ ﺍﻳﻦ ﺗﻌﺎﻣﻞ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﮐﻨﻴﻢ ﻧﺨﺴﺘﻴﻦ ﺯﺑﺎﻥ ‪،‬ﺯﺑﺎﻥ‬
‫ﺑﺮﻧﺎﻣﻪ ﻧﻮﻳﺴﻲ ﻣﺎ ﺍﺳﺖ )ﻣﺜﻼ ‪ (C#‬ﻭ ﺩﻳﮕﺮﻱ ﺯﺑﺎﻧﻲ ﮐﻪ ﺑﺎ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﺍﺭﺗﺒﺎﻁ ﺑﺮﻗﺮﺍﺭ ﻣﻲ ﮐﻨﻴﻢ )ﻣﺜﻼ ‪.(SQL‬ﺑﺮﺍﻱ ﺍﻳﻨﮑﻪ‬
‫ﺑﺘﻮﺍﻧﻴﻢ ﺑﺎ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﺍﺭﺗﺒﺎﻁ ﺑﺮﻗﺮﺍﺭ ﮐﻨﻴﻢ ﻋﺒﺎﺭﺕ ‪ SQL‬ﺭﺍ ﺩﺭ ﻗﺎﻟﺐ ﻣﺘﻦ ﺑﻪ ﺳﻴﺴﺘﻢ ﻣﻴﺎﻣﻨﺠﻲ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﺍﺭﺳﺎﻝ ﻣﻲ ﮐﻨﻴﻢ‬
‫ﮐﻪ ﺗﺎ ﺯﻣﺎﻥ ﺍﺟﺮﺍ ﻧﺸﺪﻥ ﮐﺪ ﻧﻤﻲ ﺗﻮﺍﻧﻴﻢ ﺍﺯ ﺻﺤﺖ ﺍﻳﻦ ﻋﺒﺎﺭﺕ ﻣﻄﻠﻊ ﺷﻮﻳﻢ‪.‬‬

‫ﺩﺭ ‪ C# 3.0‬ﺗﮑﻨﻮﻟﻮﮊﻱ ‪ LINQ‬ﻣﺎ ﺭﺍ ﺍﺯ ﻭﺍﺑﺴﺘﻪ ﺑﻮﺩﻥ ﺑﻪ ﻋﺒﺎﺭﺍﺕ ‪ SQL‬ﻣﺘﻨﻲ ﺭﻫﺎ ﺳﺎﺧﺖ ﻭ ﺑﻮﺳﻴﻠﻪ ﻋﺒﺎﺭﺍﺕ ﭘﺮﺱ ﻭ ﺟﻮ‬
‫ﻗﺎﺑﻠﻴﺖ ﻧﻮﺷﺘﻦ ﻋﺒﺎﺭﺍﺗﻲ ﻧﺰﺩﻳﮏ ﺑﻪ ﻋﺒﺎﺭﺍﺕ ‪ SQL‬ﺑﺎ ﻗﺎﺑﻠﻴﺖ ‪ Language-Level‬ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﻋﺒﺎﺭﺍﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﺑﺎ ﺟﺮﺀ ‪ from‬ﺷﺮﻭﻉ ﻭ ﺑﺎ ‪ select‬ﻭ ﻳﺎ ‪ group‬ﺑﻪ ﭘﺎﻳﺎﻥ ﻣﻲ ﺭﺳﺪ‪.‬ﺟﺰﺀ ‪ from‬ﻣﻲ ﺗﻮﺍﻧﺪ ﺑﺎ ﺟﺰﺀ‬
‫ﻫﺎﻱ ‪ let ¡ from‬ﻭ ‪ where‬ﺍﺩﺍﻣﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﺪ‪ .‬ﺟﺰﺀ ‪ from‬ﻧﻘﺶ ﺳﺎﺯﻧﺪﻩ ‪ let،‬ﻧﻘﺶ ﻣﺤﺎﺳﺒﻪ ﮔﺮ ﻣﻘﺪﺍﺭ ‪select ،‬‬
www.AliAghdam.ir LINQ ‫ ﺑﺮﺍﻱ‬C# ‫ | ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ‬17 ‫ﺻﻔﺤﻪ‬

‫ ﺟﺰﺀ ﻫﺎﻱ ﺩﻳﮕﺮ ﻧﻴﺰ ﻭﺟﻮﺩ ﺩﺍﺭﻧﺪ ﮐﻪ ﺩﺭ‬.‫ ﻧﻘﺶ ﻓﻴﻠﺘﺮ ﺭﺍ ﺍﻳﻔﺎ ﻣﻲ ﮐﻨﻨﺪ‬where ‫ ﻧﻘﺶ ﺷﮑﻞ ﺩﺍﺩﻥ ﺑﻪ ﻧﺘﺎﻳﺞ ﻭ‬group ‫ﻭ‬
.‫ﻓﺼﻞ ﺑﻌﺪﻱ ﺑﻪ ﺗﻔﻀﻴﺎ ﺁﻧﻬﺎ ﺭﺍ ﺷﺮﺡ ﺧﻮﺍﻫﻴﻢ ﺩﺍﺩ‬

:‫ﻗﺎﻋﺪﻩ ﻧﻮﺷﺘﺎﺭ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬


Query-expression:
from-clause query-body

from-clause:
from typeopt identifier in expression join-clausesopt

join-clauses:
join-clause
join-clauses join-clause

join-clause:
join typeopt identifier in expression on expression equals expression
join typeopt identifier in expression on expression equals expression
into identifier

query-body:
from-let-where-clausesopt orderby-clauseopt select-or-group-clause query-
continuationopt

from-let-where-clauses:
from-let-where-clause
from-let-where-clauses from-let-where-clause

from-let-where-clause:
from-clause
let-clause
where-clause

let-clause:
let identifier = expression

where-clause:
where boolean-expression

orderby-clause:
orderby orderings

orderings:
18‫ |ﺻﻔﺤﻪ‬LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

ordering
orderings , ordering

ordering:
expression ordering-directionopt

ordering-direction:
ascending
descending

select-or-group-clause:
select-clause
group-clause

select-clause:
select expression

group-clause:
group expression by expression

query-continuation:
into identifier join-clausesopt query-body

‫ﺩﺭ ﻭﺍﻗﻊ ﺍﻳﻦ ﻋﺒﺎﺭﺍﺕ ﺩﺭ ﻫﻨﮕﺎﻡ ﮐﺎﻣﭙﺎﻳﻞ ﺑﻪ ﺷﮑﻞ ﻣﺘﺪﻱ ﺧﻮﺩ ﺑﻪ ﻭﺳﻴﻠﻪ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺗﺒﺪﻳﻞ ﻣﻲ ﮔﺮﺩﻧﺪ ﻭ ﺷﻤﺎ ﻧﻴﺰ ﻣﻲ‬
‫ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮﻱ ﺯﻳﺮ ﺭﺍ ﺩﺭ ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ‬.‫ﺗﻮﺍﻧﻴﺪ ﺑﻪ ﺻﻮﺭﺕ ﻣﺴﺘﻘﻴﻢ ﺷﮑﻞ ﻣﺘﺪﻱ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﺭﺍ ﺑﻨﻮﻳﺴﻴﺪ‬

from Person p in Persons


where p.LName == "Aghdam"
select p

:‫ﻋﺒﺎﺭﺕ ﺑﺎﻻ ﺍﺑﺘﺪﺍ ﺑﻪ ﻋﺒﺎﺭﺕ ﺯﻳﺮ ﺗﺒﺪﻳﻞ ﻣﻲ ﮔﺮﺩﺩ‬

from Person p in Persons.Cast<Person>()


where p.Lname == "Aghdam"
select p
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 19‬ﻓﺼﻞ ﺩﻭﻡ – ﺧﺼﻮﺻﻴﺎﺕ ﺟﺪﻳﺪ ‪ C#‬ﺑﺮﺍﻱ ‪LINQ‬‬

‫ﻋﺒﺎﺭﺕ ﺑﺎﻻ ﺍﺑﺘﺪﺍ ﺑﻪ ﻋﺒﺎﺭﺕ ﺯﻳﺮ ﺗﺒﺪﻳﻞ ﻣﻲ ﮔﺮﺩﺩ‪:‬‬

‫)"‪Persons.Cast<Person>().Where( p => p.LName == "Aghdam‬‬


‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫‪3‬‬ ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭﺟﻮ‪ API ϭ‬ﺍﻱ ﺍﺳﺖ ﮐﻪ ﺍﻣﮑﺎﻥ ﺍﻧﺠﺎﻡ ﭘﺮﺱ ﻭ ﺟﻮ ﺭﺍ ﺑﺮ ﺭﻭﻱ ﺁﺭﺍﻳﻪ ﻫﺎ ﻭ‬
‫ﻣﺠﻤﻮﻋﻪ ﻫﺎ ﻭ ﺍﻧﻮﺍﻉ ﻣﻨﺎﺑﻊ ﺩﺍﺩﻩ ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭﺟﻮ ﺩﺭ ﻭﺍﻗﻊ ﺗﻮﺍﺑﻌﻲ ﻫﺴﺘﻨﺪﮐﻪ ﺩﺭﮐﻼﺱ ﻫﺎﻱ ﺍﻳﺴﺘﺎﻱ ﻣﻮﺟﻮﺩ ﺩﺭ ﻓﻀﺎﻱ ﻧﺎﻡ‬
‫‪ System.Linq‬ﻭ ﺑﻪ ﻋﻨﻮﺍﻥ ﻣﺘﺪﻫﺎﻱ ﺗﻮﺳﻌﻪ ﺑﺎ ﻣﺪﻝ ﻫﺎﻱ ﻣﺨﺘﻠﻔﻲ ﺗﻌﺮﻳﻒ ﺷﺪﻩ ﺍﻧﺪ‪ .‬ﺍﻳﻦ ﺗﻮﺍﺑﻊ ﺩﺭ ﺍﺳﻤﺒﻠﻲ‬
‫‪ System.Core.dll‬ﻗﺮﺍﺭ ﺩﺍﺭﻧﺪ ¡ ﻭ ﺍﺯ ﺁﻥﻫﺎ ﺩﺭ ﻫﺮ ﺯﺑﺎﻥ ﺗﺤﺖ ﺩﺍﺕ ﻧﺘﻲ ﮐﻪ ‪ Generic‬ﻫﺎ ﻭ ﻭﻳﮋﮔﻲ ﻫﺎﻱ ﺟﺪﻳﺪ ﺩﺍﺕ ﻧﺖ‬

‫>‪IEnumerable<T‬ﻭ‬
‫ﺭﺍ ﭘﺸﺘﻴﺒﺎﻧﻲ ﮐﻨﺪ¡ ﻣﻲ ﺗﻮﺍﻥ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‪.‬‬

‫ﺍﺯ ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ ﻣﻲ ﺗﻮﺍﻥ ﺑﺮ ﺭﻭﻱ ﻫﺮ ﺷﺊ ﮐﻪ ﻭﺍﺳﻂ‬


‫>‪ IQueryable<T‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﻨﺪ‪ ،‬ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﮐﻪ ﺑﻪ ﺟﺎﻱ ‪ T‬ﻣﻲ ﺗﻮﺍﻥ ﻫﺮ ﻧﻮﻉ ﺩﻳﮕﺮﻱ ﻗﺮﺍﺭ‬
‫ﺩﺍﺩ‪.‬‬

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


‫‪Order‬‬ ‫ﺍﺯ ﺍﻳﻦ ﻗﺴﻤﺖ ﺑﻪ ﺑﻌﺪ ﺑﺮﺍﻱ ﺗﻮﺿﻴﺢ ﻣﺜﺎﻝ ﻫﺎﻱ ﺩﺭ ﻣﻮﺭﺩ ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ ﺍﺯ ﺳﻪ ﮐﻼﺱ‬
‫¡‪ Customer‬ﻭ ‪ Product‬ﺍﺳﺘﻔﺎﺩﻩ ﺧﻮﺍﻫﻴﻢ ﮐﺮﺩ ﮐﻪ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺁﻧﻬﺎ ﺩﺭ ﺿﻤﻴﻤﻪ ﺷﻤﺎﺭﻩ ﻳﮏ ﻣﻮﺟﻮﺩ ﺍﺳﺖ‪.‬‬

‫‪1‬‬
‫‪Standard Query Operators‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 21‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﺍﻧﻮﺍﻉ ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭﺟﻮ‬

‫ﺩﺭ ﺯﻳﺮ ﻟﻴﺴﺘﻲ ﺍﺯ ﺍﻧﻮﺍﻉ ﺍﻳﻦ ﻋﻤﻠﮕﺮﻫﺎ ﺁﻣﺪﻩ ﺍﺳﺖ ﮐﻪ ﺍﺩﺍﻣﻪ ﻫﺮ ﮐﺪﺍﻡ ﺭﺍ ﺑﻪ ﻃﻮﺭ ﮐﺎﻣﻞ ﺗﻮﺿﻴﺢ ﺧﻮﺍﻫﻢ ﺩﺍﺩ‪.‬‬

‫ﺗﻮﺿﻴﺤﺎﺕ‬ ‫ﻋﻤﻠﮕﺮ‬ ‫ﻋﻤﻠﻴﺎﺕ‬


‫ﻳﮏ ﺗﺎﺑﻊ ﺭﺍ ﺑﺮ ﺭﻭﻱ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﻋﻤﺎﻝ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Aggregate‬‬
‫ﻣﻴﺎﻧﮕﻴﻦ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﻣﺤﺎﺳﺒﻪ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Average‬‬
‫ﻣﺠﻤﻮﻉ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﻣﺤﺎﺳﺒﻪ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Sum‬‬
‫ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺎ ﻳﮏ ﻧﻮﻉ ‪ int‬ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪Count‬‬ ‫‪Aggregate‬‬
‫ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺎ ﻳﮏ ﻧﻮﻉ ‪ Long‬ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪Long Count‬‬
‫ﮐﻤﺘﺮﻳﻦ ﻣﻘﺪﺍﺭ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻣﻘﺎﺩﻳﺮ ﻋﺪﺩﻱ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪Min‬‬
‫ﺑﻴﺸﺘﺮﻳﻦ ﻣﻘﺪﺍﺭ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻣﻘﺎﺩﻳﺮ ﻋﺪﺩﻱ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪Max‬‬

‫ﻋﻨﺎﺻﺮ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺎ ﻫﻢ ﺍﺩﻏﺎﻡ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Concatenatio‬‬


‫‪Concat‬‬
‫‪n‬‬
‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ ﻳﮏ ﻧﻮﻉ ﻣﻌﻴﻦ ﺷﺪﻩ ‪ ،‬ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Cast‬‬
‫ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﻣﻌﻴﻦ ﺷﺪﻩ ﻳﮏ ﺁﺭﺍﻳﻪ ﻣﻲ ﺳﺎﺯﺩ‪.‬‬ ‫‪ToArray‬‬
‫ﺍﺯ ﺭﻭﻱ ﻣﺠﻤﻮﻋﻪ ﻣﺸﺨﺺ ﺷﺪﻩ ﻳﮏ ﺷﺊ ﺍﺯ ﻧﻮﻉ ﮐﻼﺱ‬
‫‪ToDictionary‬‬
‫>‪ Dictionary<K,E‬ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫‪Conversion‬‬
‫ﺍﺯ ﺭﻭﻱ ﻣﺠﻤﻮﻋﻪ ﻣﺸﺨﺺ ﺷﺪﻩ ﻳﮏ ﺷﺊ ﺍﺯ ﻧﻮﻉ ﮐﻼﺱ >‪List<T‬‬
‫‪ToList‬‬
‫ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫ﺍﺯ ﺭﻭﻱ ﻣﺠﻤﻮﻋﻪ ﻣﺸﺨﺺ ﺷﺪﻩ ﻳﮏ ﺷﺊ ﺍﺯ ﻧﻮﻉ ﮐﻼﺱ‬
‫‪ToLookup‬‬
‫>‪ LookUp<K,T‬ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﺍﮔﺮ ﻣﺠﻤﻮﻋﻪ ﻣﺸﺨﺺ ﺷﺪﻩ ﺗﻬﻲ ﺑﺎﺷﺪ ‪ ،‬ﻳﮏ ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺽ ﺑﻪ‬
‫‪DefaultIfEmpty‬‬
‫ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﻋﻨﺼﺮﻱ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﺍﻳﻨﺪﮐﺲ ﻣﻌﻴﻦ ﺷﺪﻩ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪ElementAt‬‬


‫‪Element‬‬
‫ﻋﻨﺼﺮﻱ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﺍﻳﻨﺪﮐﺲ ﻣﻌﻴﻦ ﺷﺪﻩ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ‬
‫‪ ElementAtOrDefault‬ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺍﻳﻨﺪﮐﺲ ﺧﺎﺭﺝ ﺍﺯ ﻣﺤﺪﻭﺩﻩ ﺑﺎﺷﺪ ﻳﮏ ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺽ‬
‫ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬
‫|ﺻﻔﺤﻪ‪22‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﺗﻮﺿﻴﺤﺎﺕ‬ ‫ﻋﻤﻠﮕﺮ‬ ‫ﻋﻤﻠﻴﺎﺕ‬


‫ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪First‬‬
‫ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ ﺍﮔﺮ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﺩﺭ‬
‫‪FirstOrDefault‬‬
‫ﺩﺳﺘﺮﺱ ﻧﺒﺎﺷﺪ ﻳﮏ ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺽ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬
‫ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪Last‬‬

‫ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ ﺍﮔﺮ ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﺩﺭ‬


‫‪LastOrDefault‬‬
‫ﺩﺳﺘﺮﺱ ﻧﺒﺎﺷﺪ ﻳﮏ ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺽ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬

‫ﻳﮏ ﻋﻨﺼﺮ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﮐﻪ ﺑﺎ ﺷﺮﻁ ﻣﻄﺎﺑﻘﺖ ﺩﺍﺷﺘﻪ ﺭﺍ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ‬


‫‪Single‬‬
‫ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬
‫ﻳﮏ ﻋﻨﺼﺮ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﮐﻪ ﺑﺎ ﺷﺮﻁ ﻣﻄﺎﺑﻘﺖ ﺩﺍﺷﺘﻪ ﺭﺍ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ‬
‫ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ ﺍﮔﺮ ﻋﻨﺼﺮﻱ ﭘﻴﺪﺍ ﻧﺸﻮﺩ ﻳﮏ ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺽ ﺑﺮ ﻣﻲ‬ ‫‪SingleOrDefault‬‬
‫ﮔﺮﺩﺍﻧﺪ‪.‬‬
‫ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮﺍﻱ ﻳﮑﺴﺎﻥ ﺑﻮﺩﻥ ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﺪ ﻭ ﻣﻘﺪﺍﺭ‬
‫‪SequenceEqual‬‬ ‫‪Equality‬‬
‫‪ Boolean‬ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‬

‫ﺍﺯ ﻧﻮﻉ ﺗﻌﻴﻴﻦ ﺷﺪﻩ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺗﻬﻲ ﺳﺎﺧﺘﻪ ﻭ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪Empty‬‬

‫ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﻋﺪﺩﻱ ﺭﺍ ﺷﺎﻣﻞ ﻋﻨﺎﺻﺮﻱ ﺍﺯ ﭘﺎﺭﺍﻣﺘﺮ ﺍﻭﻝ ﻭﺭﻭﺩﻱ ﺗﺎ ﭘﺎﺭﺍﻣﺘﺮ‬


‫‪Range‬‬
‫ﺩﻭﻡ ﻭﺭﻭﺩﻱ ﺭﺍ ﺳﺎﺧﺘﻪ ﻭ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪Generation‬‬
‫ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﮐﻪ ﺷﺎﻣﻞ ﺗﮑﺮﺍﺭﻫﺎﻱ ﺍﺯ ﻋﻨﺼﺮ ﺗﻌﻴﻴﻦ ﺷﺪﻩ ﺍﺳﺖ ﻭ ﺑﺮ‬
‫‪Repeat‬‬
‫ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬

‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﮔﺮﻭﻩ ﺑﻨﺪﻱ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪GroupBy‬‬ ‫‪Grouping‬‬


‫ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﮐﻠﻴﺪﻫﺎﻱ ﻫﻤﺴﺎﻥ ﮔﺮﻭﻩ ﺑﻨﺪﻱ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪GroupJoin‬‬

‫ﺍﺗﺼﺎﻝ ﺩﺍﺧﻠﻲ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﮐﻠﻴﺪﻫﺎﻱ ﻫﻤﺴﺎﻥ ﺍﻧﺠﺎﻡ ﻣﻲ‬ ‫‪Join‬‬


‫‪Join‬‬
‫ﺩﻫﺪ‪.‬‬

‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﻭ ﻳﺎ ﭼﻨﺪ ﮐﻠﻴﺪ ﻣﻌﻴﻦ ﺑﻪ ﺻﻮﺭﺕ‬


‫‪OrderBy‬‬
‫ﺻﻌﻮﺩﻱ ﻣﺮﺗﺐ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫‪Ordering‬‬
‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﻭ ﻳﺎ ﭼﻨﺪ ﮐﻠﻴﺪ ﻣﻌﻴﻦ ﺑﻪ ﺻﻮﺭﺕ‬
‫‪OrderByDescending‬‬
‫ﻧﺰﻭﻟﻲ ﻣﺮﺗﺐ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 23‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﺗﻮﺿﻴﺤﺎﺕ‬ ‫ﻋﻤﻠﮕﺮ‬ ‫ﻋﻤﻠﻴﺎﺕ‬


‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﻣﺮﺗﺐ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﻭ ﻳﺎ ﭼﻨﺪ ﮐﻠﻴﺪ ﺑﻪ ﺻﻮﺭﺕ‬
‫‪ThenBy‬‬
‫ﺻﻌﻮﺩﻱ ﻣﺮﺗﺐ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﻣﺮﺗﺐ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﻭ ﻳﺎ ﭼﻨﺪ ﮐﻠﻴﺪ ﺑﻪ ﺻﻮﺭﺕ‬
‫‪ThenByDescending‬‬
‫ﻧﺰﻭﻟﻲ ﻣﺮﺗﺐ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫ﺗﻤﺎﻣﻲ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺍﺯ ﻧﻈﺮ ﭼﻴﺪﻣﺎﻥ ﺑﺮﻋﮑﺲ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Reverse‬‬
‫ﺑﻪ ﺗﻌﺪﺍﺩ ﻣﺸﺨﺺ ﺷﺪﻩ ﺍﻱ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺻﺮﻑ ﻧﻈﺮ ﮐﺮﺩﻩ ﻭ ﺑﻘﻴﻪ‬
‫‪Skip‬‬
‫ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬
‫ﺑﻪ ﻭﺳﻴﻠﻪ ﻳﮏ ﻋﺒﺎﺭﺕ ﺷﺮﻃﻲ ‪ ،‬ﺍﺯ ﺗﻌﺪﺍﺩ ﻣﺸﺨﺼﻲ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
‫‪SkipWhile‬‬
‫ﺻﺮﻑ ﻧﻈﺮ ﮐﺮﺩﻩ ﻭ ﺑﻘﻴﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬
‫‪Partitioning‬‬
‫ﺗﻌﺪﺍﺩ ﻣﺸﺨﺼﻲ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻭ ﺍﺯ‬
‫‪Take‬‬
‫ﺑﺎﻗﻴﻤﺎﻧﺪﻩ ﻋﻨﺎﺻﺮ ﺻﺮﻑ ﻧﻈﺮ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫ﺗﻌﺪﺍﺩ ﻣﺸﺨﺼﻲ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻮﺳﻴﻠﻪ ﻳﮏ ﺷﺮﻁ ﺟﺪﺍ ﻭ ﺑﻪ ﻋﻨﻮﺍﻥ‬
‫‪TakeWhile‬‬
‫ﺧﺮﻭﺟﻲ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻭ ﺍﺯ ﺑﺎﻗﻴﻤﺎﻧﺪﻩ ﻋﻨﺎﺻﺮ ﺻﺮﻑ ﻧﻈﺮ ﻣﻲ ﮐﻨﺪ‪.‬‬
‫ﻋﻨﺎﺻﺮﻱ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﮐﻪ ﻣﻲ ﺑﺎﻳﺴﺖ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﺷﻮﻧﺪ ﺭﺍ ﺗﻌﻴﻴﻦ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Select‬‬
‫‪Projection‬‬
‫ﻳﮏ ﻋﻤﻠﻴﺎﺕ ﭘﺮﺗﻮ ﻳﮏ ﺑﻪ ﭼﻨﺪ ﺍﺯ ﺭﻭﻱ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺍﻧﺠﺎﻡ ﻣﻲ ﺩﻫﺪ‪.‬‬ ‫‪SelectMany‬‬

‫ﮐﻠﻴﻪ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﺷﺮﻁ ﻣﺸﺨﺺ ﭼﮏ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪All‬‬


‫ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﺁﻳﺎ ﻋﻨﺼﺮﻱ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﺑﺎ ﺷﺮﻁ ﺩﺍﺩﻩ ﺷﺪﻩ ﻣﻄﺎﺑﻘﺖ‬
‫‪Any‬‬ ‫‪Quantifier‬‬
‫ﻣﻲ ﮐﻨﺪ ﻳﺎ ﻧﻪ‪.‬‬
‫ﻭﺟﻮﺩ ﻋﻨﺼﺮ ﻣﻮﺭﺩ ﻧﻈﺮ ﺭﺍ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Contains‬‬

‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻣﺸﺨﺺ ﺷﺪﻩ ﻓﻴﻠﺘﺮ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Where‬‬


‫‪Restriction‬‬
‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﻧﻮﻉ ﻣﻌﻴﻦ ﺷﺪﻩ ‪ ،‬ﻓﻴﻠﺘﺮ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪OfType‬‬

‫ﻋﻨﺎﺻﺮ ﻣﺘﻤﺎﻳﺰ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬ ‫‪Distinct‬‬


‫ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﺭﺍ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺘﻔﺎﻭﺕ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﻣﺠﺰﺍ ﺍﻳﺠﺎﺩ ﻣﻲ‬
‫‪Except‬‬
‫ﮐﻨﺪ‪.‬‬
‫ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﺭﺍ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺸﺎﺑﻪ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﻣﺠﺰﺍ ﺍﻳﺠﺎﺩ ﻣﻴﮑﻨﺪ‪.‬‬ ‫‪Intersect‬‬ ‫‪Set‬‬
‫ﺍﺯ ﺣﺎﺻﻞ ﺍﺟﺘﻤﺎﻉ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ‪.‬‬ ‫‪Union‬‬
‫ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺎ ﻋﻨﺎﺻﺮ ﻣﺘﻨﺎﻇﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺩﻳﮕﺮ ﺍﺩﻏﺎﻡ ﻣﻲ‬
‫‪Zip‬‬
‫ﮐﻨﺪ‬
‫|ﺻﻔﺤﻪ‪24‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﺗﻮﺿﻴﺤﺎﺕ‬ ‫ﻋﻤﻠﮕﺮ‬ ‫ﻋﻤﻠﻴﺎﺕ‬


‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻧﻮﻉ‬
‫‪AsEnumerable‬‬
‫>‪ IEnumerable<TSource‬ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﻋﻤﻠﮕﺮ ﺷﺮﻃﻲ ‪Restriction Operator -‬‬


‫ﻋﻤﻠﮕﺮ ﺷﺮﻃﻲ ﻧﺘﻴﺠﻪ ﭘﺮﺱ ﻭ ﺟﻮ ﻫﺎ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﺷﺮﻁ ﺗﻌﻴﻴﻦ ﺷﺪﻩ ﻓﻴﻠﺘﺮ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﺍﺯ ﭘﺮﮐﺎﺭﺑﺮﺩ ﺗﺮﻳﻦ ﻋﻤﻠﮕﺮﻫﺎﻱ‬
‫ﭘﺮﺱ ﻭ ﺟﻮ ﺩﺭ ‪ LINQ‬ﺍﺳﺖ‪ .‬ﺩﺭ ﺍﺩﺍﻣﻪ ﺑﻪ ﺑﺮﺭﺳﻲ ﺍﻳﻦ ﻧﻮﻉ ﻋﻤﻠﮕﺮ ﺧﻮﺍﻫﻴﻢ ﭘﺮﺩﺍﺧﺖ‪.‬‬

‫ﻋﻤﻠﮕﺮ ‪Where‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻧﺘﻴﺠﻪ ﭘﺮﺱ ﻭﺟﻮ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﺁﺭﮔﻮﻣﺎﻥ ﻭﺭﻭﺩﻱ )ﺑﻪ ﻋﻨﻮﺍﻥ ﺷﺮﻁ( ﻣﺤﺪﻭﺩ ﻣﻲ ﮐﻨﺪ‪ .‬ﻓﺮﻡ ﮐﻠﻲ ﻧﻮﺷﺘﺎﺭ ﺍﻳﻦ‬
‫ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ ‪:‬‬

‫(>‪public static IEnumerable<TSource> Where<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫(>‪public static IEnumerable<TSource> Where<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Int32, Boolean> predicate‬‬

‫ﺗﻔﺎﻭﺕ ﺍﻳﻦ ﺩﻭ ﻓﺮﻡ ﺍﺯ ﻋﻤﻠﮕﺮ ‪ Where‬ﺗﻨﻬﺎ ﺩﺭ ﭘﺎﺭﺍﻣﺘﺮ ﺩﻭﻡ ﺁﻧﻬﺎ ﺍﺳﺖ ﺍﻳﻦ ﭘﺎﺭﺍﻣﺘﺮ ﻫﻤﺎﻥ ﺷﺮﻃﻲ ﺍﺳﺖ ﮐﻪ ﻫﺮ ﻋﻨﺼﺮ ﺩﺭ‬
‫ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺑﺎ ﺁﻥ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﮔﺮﺩﺩ‪ .‬ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﻋﻤﻠﮕﺮ ‪ Where‬ﻳﮏ ﭘﺎﺭﺍﻣﺘﺮ ﺍﺯ ﻧﻮﻉ ‪ int‬ﻭﺟﻮﺩ ﺩﺍﺭﺩ ﮐﻪ ﻧﺸﺎﻥ ﺩﻫﻨﺪﻩ‬
‫ﺍﻧﺪﻳﺲ ﻫﺮ ﻋﻀﻮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺍﺳﺖ ﮐﻪ ﺻﻔﺮ ﺷﺮﻭﻉ ﻣﻲ ﺷﻮﺩ‪.‬‬

‫ﻣﺜﺎﻝ ‪ :1‬ﺩﺭ ﭘﺮﺱ ﻭ ﺟﻮﻱ ﺯﻳﺮ ﺍﺟﻨﺎﺳﻲ ﮐﻪ ﻗﻴﻤﺖ ﺁﻧﻬﺎ ﺑﻴﺸﺘﺮ ﺍﺯ‪ 10‬ﺑﺎﺷﺪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ‪.‬‬

‫>‪List<Product> products = new List<Product‬‬


‫{‬ ‫‪new Product() { Name = "product 1", UnitPrice = 10 },‬‬
‫‪new Product() { Name = "product 2", UnitPrice = 8 },‬‬
‫} ‪new Product() { Name = "product 3", UnitPrice = 12‬‬
‫;}‬

‫‪IEnumerable<Product> retProducts = from p in products‬‬


‫‪where p.UnitPrice > 10‬‬
‫;‪select p‬‬

‫)‪foreach (var item in retProducts‬‬


‫;)‪Console.WriteLine(item.Name‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 25‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻭﻗﺘﻲ ﭘﺮﺱ ﻭﺟﻮﻱ ﻗﺒﻞ ﮐﺎﻣﭙﺎﻳﻞ ﻡﻱ ﮔﺮﺩﺩ ﺑﻪ ﻣﻌﺎﺩﻝ ﺗﻮﺍﺑﻊ ﺍﻟﺤﺎﻗﻲ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮﺩ ﻭ ﺩﺭ ﻭﺍﻗﻊ ﺗﻮﺍﺑﻊ ﺍﻟﺤﺎﻗﻲ ﻫﺴﺘﻨﺪ ﻭﻟﻲ‬
‫ﺑﺮﺍﻱ ﺍﻳﻨﮑﻪ ﺑﺘﻮﺍﻥ ﺍﺯ ﻓﺮﻡ ﭘﺮﺱ ﻭﺟﻮﻱ ﺷﺒﻴﻪ ﺑﻪ ﻧﻮﺷﺘﺎﺭ ‪ SQL‬ﺍﺳﺘﻔﺎﺩﻩ ﮎﺭﺩ ﺑﻪ ﺍﻳﻦ ﺻﻮﺭﺕ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﻧﺪ ﮐﻪ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ‬
‫ﮎﺩ‪ .‬ﺑﻪ ﻋﻨﻮﺍﻥ ﻣﺜﺎﻝ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﺑﺎﻻ ﺩﺭ ﻫﻨﮕﺎﻡ ﮐﺎﻣﭙﺎﻳﻞ ﺑﻪ ﻋﺒﺎﺭﺕ‬
‫ﻫﺮ ﺩﻭ ﻓﺮﻡ ﺏﺭﺍﻱ ﻧﻮﺷﺘﻦ ﭘﺮﺱ ﻭﺟﻮ ﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﺭ‬
‫ﺯﻳﺮ ﺗﺒﺪﻳﻞ ﻣﻲ ﺷﻮﻧﺪ ‪ ،‬ﺑﻪ ﻧﺤﻮﻩ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﻭ ﻋﺒﺎﺭﺍﺕ ﻻﻣﺒﺪﺍ ﺗﻮﺟﻪ ﮐﻨﻴﺪ ‪.‬‬

‫;)‪IEnumerable<Product> retProducts = products.Where(p => p.UnitPrice > 10‬‬

‫ﻣﺜﺎﻝ ‪ :2‬ﺩﺭ ﺑﺮﻧﺎﻣﻪ ﺯﻳﺮ ﺍﺯ ﻧﻮﻉ ﺩﻭﻡ ﻋﻤﻠﮕﺮ ﺍﺳﺘﻔﺎﺩﻩ ﺷﺪﻩ ﺍﺳﺖ‪ .‬ﺩﺭ ﺍﻳﻦ ﺑﺮﻧﺎﻣﻪ ﺧﺮﻳﺪﺍﺭﺍﻧﻲ ﮐﻪ ﮐﺪ ﺍﻳﻨﺪﮐﺲ ﺁﻧﻬﺎ ﺑﺎ ﮐﺪ ‪ID‬ﺷﺎﻥ‬
‫ﺑﺮﺍﺑﺮ ﺑﺎﺷﺪ ‪ ،‬ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﻧﺪ‪.‬‬

‫= ‪List<Customer> customers‬‬ ‫)(>‪new List<Customer‬‬


‫{‬
‫‪new Customer() {Name‬‬ ‫"‪="Ali‬‬ ‫‪, Family = "Aghdam" , CustomerID =0 },‬‬
‫‪new Customer() {Name‬‬ ‫"‪="Ali‬‬ ‫‪, Family = "Nasiri" , CustomerID =2 },‬‬
‫‪new Customer() {Name‬‬ ‫} ‪="Arash" , Family = "Novin" , CustomerID =3‬‬
‫;}‬

‫;) ‪var query = customers.Where( ( p , index ) => p.CustomerID == index‬‬

‫) ‪foreach (var item in query‬‬


‫;)‪Console.WriteLine(item.Name‬‬

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


‫ﺍﮔﺮ ﻫﺮ ﻳﮏ ﺍﺯ ﺁﺭﮔﻮﻣﺎﻥ ﻫﺎﻱ ﻋﻤﻠﮕﺮ ‪ Where‬ﺑﺎ ‪ null‬ﻣﻘﺪﺍﺭ ﺩﻫﻲ ﺷﻮﻧﺪ ﻳﮏ ﺍﺳﺘﺜﻨﺎﺀ ‪ ArgumentNullExceptio‬ﺗﻮﻟﻴﺪ‬
‫ﺧﻮﺍﻫﺪ ﺷﺪ‪.‬‬

‫ﻋﻤﻠﮕﺮ ‪OfType‬‬
‫ﻋﻤﻠﮕﺮ ‪ OfType‬ﺍﻋﻀﺎﺀ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮﺣﺴﺐ ﻳﮏ ﻧﻮﻉ ﻣﺸﺨﺺ ﻓﻴﻠﺘﺮ ﻣﻲ ﮐﻨﺪ ﻭ ﻓﻘﻂ ﻋﻨﺎﺻﺮﻱ ﮐﻪ ﺍﺯ ﺁﻥ ﻧﻮﻉ‬
‫ﺑﺎﺷﻨﺪ ﺩﺭ ﻧﺘﻴﺠﻪ ﭘﺮﺱ ﻭ ﺟﻮ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﻧﺪ‪ .‬ﻓﺮﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ ‪:‬‬

‫{)‪public static IEnumerable<T> OfType<T>(this IEnumerable source‬‬


‫)‪foreach (object item in source‬‬
26‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

if (item is T)
yield return (T)item;
}

T ‫ ﺗﮏ ﺗﮏ ﺑﺮﺭﺳﻲ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺑﺎ ﻧﻮﻉ‬source ‫ﻫﻤﺎﻧﻄﻮﺭ ﮐﻪ ﺍﺯ ﻓﺮﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻌﻠﻮﻡ ﺍﺳﺖ ﺍﻋﻀﺎﻱ‬
.‫ﻣﻄﺎﺑﻘﺖ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻨﺪ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﻧﺪ‬

‫ ﻫﺴﺘﻨﺪ ﺭﺍ‬Customer ‫ ﺩﺭ ﺑﺮﻧﺎﻣﻪ ﺯﻳﺮ ﻣﻲ ﺧﻮﺍﻫﻴﻢ ﺍﺯ ﺑﻴﻦ ﺍﻧﻮﺍﻉ ﻣﺨﺘﻠﻒ ﺩﺭﻭﻥ ﻟﻴﺴﺖ ﻓﻘﻂ ﻋﻨﺎﺻﺮﻱ ﮐﻪ ﺍﺯ ﻧﻮﻉ‬:‫ﻣﺜﺎﻝ‬
.‫ﺍﻧﺘﺨﺎﺏ ﮐﻨﻴﻢ‬

//using System.Collections

ArrayList complexList = new ArrayList();

complexList.Add("Test String 1");


complexList.Add(new DateTime(2011,1,1));
complexList.Add(10);

complexList.Add(new Customer() {Name = "Ali" , Family ="Aghdam"});

var query = complexList.OfType<Customer>();

foreach (var item in query)


Console.WriteLine( item.Name + " " + item.Family );

.‫ ﺭﺍ ﻧﻤﺎﻳﺶ ﻣﻲ ﺩﻫﺪ‬OfType ‫ﻣﺜﺎﻝ ﺑﺎﻻ ﺑﻪ ﺻﻮﺭﺕ ﮐﺎﻣﻼ ﺩﻗﻴﻖ ﻧﺤﻮﻩ ﮐﺎﺭﮐﺮﺩ ﻋﻤﻠﮕﺮ‬

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


‫ ﺗﻮﻟﻴﺪ‬ArgumentNullExceptio ‫ ﻣﻘﺪﺍﺭ ﺩﻫﻲ ﺷﻮﻧﺪ ﻳﮏ ﺍﺳﺘﺜﻨﺎﺀ‬null ‫ ﺑﺎ‬OfType ‫ﺍﮔﺮ ﻫﺮ ﻳﮏ ﺍﺯ ﺁﺭﮔﻮﻣﺎﻥ ﻫﺎﻱ ﻋﻤﻠﮕﺮ‬
.‫ﺧﻮﺍﻫﺪ ﺷﺪ‬
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬27 ‫ﺻﻔﺤﻪ‬

Projection Oprators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﭘﺮﺗﻮ‬


‫ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﺗﻐﻴﻴﺮ ﺷﮑﻞ ﺩﺍﺩﻥ ﺍﻋﻀﺎﺀ ﻣﺠﻤﻮﻋﻪ ﻭ ﺍﻧﺘﻘﺎﻝ ﺁﻥ ) ﺁﻧﻬﺎ ( ﺑﻪ ﻣﺠﻤﻮﻋﻪ ﺩﻳﮕﺮ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ ﺍﻟﺒﺘﻪ‬
.‫ ﺩﺭ ﺍﺩﺍﻣﻪ ﺍﻳﻦ ﻋﻤﻠﮕﺮﻫﺎ ﺭﺍ ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﻴﻢ‬.‫ﻣﻲ ﺗﻮﺍﻥ ﺍﻋﻀﺎﺀ ﻣﺠﻤﻮﻋﻪ ﺍﻭﻝ ﺭﺍ ﺑﺪﻭﻥ ﺗﻐﻴﻴﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺩﻭﻡ ﻗﺮﺍﺭ ﺩﺍﺩ‬

Select ‫ﻋﻤﻠﮕﺮ‬
‫ ﻓﺮﻡ ﮐﻠﻲ‬.‫ ﺷﺊ ﺟﺪﻳﺪ ﻭ ﻗﺎﺑﻞ ﺷﻤﺎﺭﺷﻲ ﺍﻳﺠﺎﺩ ﮐﺮﺩﻩ ﻭ ﺁﻥ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‬، ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﺯ ﺭﻭﻱ ﺁﺭﮔﻮﻣﺎﻥ ﻫﺎﻱ ﻭﺭﻭﺩﻱ‬
: ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static IEnumerable<S> Select<T, S>(this IEnumerable<T> source,


Func<T, S> selector);

public static IEnumerable<S> Select<T, S>(this IEnumerable<T> source,


Func<T, int, S> selector);

‫ ﺗﻔﺎﻭﺕ ﺩﻭ ﻓﺮﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﭘﺎﺭﺍﻣﺘﺮ ﺩﻭﻡ ﺁﻧﻬﺎ ﺍﺳﺖ ﮐﻪ ﻧﻮﻉ ﺩﻭﻡ ﻳﮏ‬.‫ ﺍﺳﺖ‬SQL ‫ ﺩﺭ‬Select ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ﻣﺎﺩﻩ‬
.‫ﺍﻧﺪﻳﺲ )ﺷﺮﻭﻉ ﺍﺯ ﺻﻔﺮ ( ﮐﻪ ﻧﺸﺎﻥ ﺩﻫﻨﺪﻩ ﻣﺤﻞ ﻫﺮ ﻋﻨﺼﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺍﺳﺖ ﺭﺍ ﺩﺭﻳﺎﻓﺖ ﻣﻲ ﮐﻨﺪ‬

(SQL ‫ ﺩﺭ‬SELECT * ‫ ﺩﺭ ﺑﺮﻧﺎﻣﻪ ﺯﻳﺮ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﻫﻤﻪ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ )ﻣﻌﺎﺩﻝ‬: 1 ‫ﻣﺜﺎﻝ‬

List<Customer> customers = new List<Customer>()


{
new Customer() {Name ="Ali" , Family = "Aghdam" , CustomerID =0 },
new Customer() {Name ="Ali" , Family = "Nasiri" , CustomerID =2 },
new Customer() {Name ="Arash" , Family = "Novin" , CustomerID =3 }
};

var query = from c in customers


select c;

foreach (var item in query)


Console.WriteLine(item.Name + " " + item.Family);

‫ ﺩﺭ ﺑﺮﻧﺎﻣﻪ ﺯﻳﺮ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﻫﻤﻪ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺑﻪ ﻫﻤﺮﺍﻩ ﺍﻧﺪﻳﺲ ﻋﻨﺎﺻﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ‬: 2 ‫ﻣﺜﺎﻝ‬
( Select ‫ )ﻓﺮﻡ ﺩﻭﻡ ﻋﻤﻠﮕﺮ‬.‫ﺷﻮﻧﺪ‬

List<Customer> customers = new List<Customer>()


{
new Customer() {Name ="Ali" , Family = "Aghdam" , CustomerID =0 },
new Customer() {Name ="Ali" , Family = "Nasiri" , CustomerID =2 },
new Customer() {Name ="Arash" , Family = "Novin" , CustomerID =3 }
};
28‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

var query = customers.Select(


(p,index) => new{position=index,p.Name, p.Family });

foreach (var item in query)


Console.WriteLine(item.Name +" "+
item.Family + ",Position= " +
item.position );

SelectMany ‫ﻋﻤﻠﮕﺮ‬
‫ ﺍﺳﺖ ﺑﺎ ﺍﻳﻦ ﺗﻔﺎﻭﺕ ﮐﻪ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ ﻧﺘﻴﺠﻪ ﭘﺮﺱ ﻭ ﺟﻮﻱ ﻗﺒﻠﻲ ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ‬Select ‫ﻋﻤﻠﮑﺮﺩ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ‬
:‫ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺍﺭﺍﻱ ﺩﻭ ﻓﺮﻡ ﮐﻠﻲ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬.‫ ﺍﺳﺖ‬SQL ‫ ﺩﺭ‬join ‫ﮐﻪ ﺩﺭ ﻭﺍﻗﻊ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮑﺮﺩ ﻣﺎﺩﻩ‬

public static IEnumerable<S> SelectMany<T, S>(this IEnumerable<T> source,


Func<T, IEnumerable<S>> selector);

public static IEnumerable<S> SelectMany<T, S>(this IEnumerable<T> source,


Func<T, int, IEnumerable<S>> selector);

‫ﻫﻤﺎﻧﻄﻮﺭ ﮐﻪ ﺩﺭ ﺑﺎﻻ ﮔﻔﺘﻪ ﺷﺪ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﻳﻦ ﻗﺎﺑﻠﻴﺖ ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻴﮑﻨﺪ ﮐﻪ ﺍﺯ ﻧﺘﻴﺠﻪ ﭘﺮﺱ ﻭ ﺟﻮﻫﺎﻱ ﻗﺒﻠﻲ ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ‬
Selector ‫ﺑﻮﺳﻴﻠﻪ ﭘﺎﺭﺍﻣﺘﺮ ﺩﻭﻡ ﻳﻌﻨﻲ‬ IEnumerable<S> ‫ﮐﻪ ﺍﻳﻦ ﺍﻣﮑﺎﻥ ﺭﺍ ﺑﻮﺳﻴﻠﻪ ﺑﺮﮔﺮﺩﺍﻧﺪﻥ ﻧﺘﻴﺠﻪ ﭘﺮﺱ ﻭ ﺟﻮ ﺍﺯ ﻧﻮﻉ‬
.‫ﺑﻮﺟﻮﺩ ﻣﻲ ﺁﻳﺪ‬
‫ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ ﻓﺮﻡ ﺩﻭﻡ ﺑﺮﺍﻱ‬IEnumerable<S> ‫ﺗﻔﺎﻭﺕ ﺍﻳﻦ ﺩﻭ ﻓﺮﻡ ﺩﺭ ﭘﺎﺭﺍﻣﺘﺮ ﺩﻭﻡ ﺍﺳﺖ ﮐﻪ ﻓﺮﻡ ﺍﻭﻝ ﻳﮏ ﻧﻮﻉ‬
.‫ ﻧﻴﺎﺯ ﺩﺍﺭﺩ‬،‫ﺑﺮﮔﺮﺩﺍﻧﺪﻥ ﻧﺘﻴﺠﻪ ﻧﻴﺎﺯ ﺑﻪ ﻳﮏ ﺍﻧﺪﻳﺲ ﺑﺮﺍﻱ ﻣﺸﺨﺺ ﺷﺪﻥ ﻣﺤﻞ ﻋﻨﺼﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺍﺳﺖ‬

.‫ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ‬،‫ ﺍﻧﺠﺎﻡ ﮔﺮﻓﺘﻪ‬2010‫ ﮐﻪ ﺑﻌﺪ ﺍﺯ ﺳﺎﻝ‬Aghdam ‫ ﺩﺭ ﺑﺮﻧﺎﻣﻪ ﺯﻳﺮ ﺳﻔﺎﺭﺵ ﻫﺎﻱ ﻣﺸﺘﺮﻱ ﺑﻪ ﻧﺎﻡ‬:‫ﻣﺜﺎﻝ‬

List<Customer> customers = new List<Customer>()


{
new Customer() {Name ="Ali" , Family = "Aghdam" , CustomerID =0 },
new Customer() {Name ="Ali" , Family = "Nasiri" , CustomerID =2 },
new Customer() {Name ="Arash" , Family = "Novin" , CustomerID =3 }
};

List<Order> order1 = new List<Order>() {


new Order(){ OrderID = 1 , OrderDate = new DateTime(2010,1,1)},
new Order(){ OrderID = 2 , OrderDate = new DateTime(2011,1,1)}
};
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬29 ‫ﺻﻔﺤﻪ‬

customers[0].Orders = order1;

var query =customers.


Where(c => c.Family == "Aghdam").
SelectMany(c =>
c.Orders.
Where(o => o.OrderDate.Year > 2010).
Select(o => new { c.Family , o.OrderID })
);

foreach (var item in query)


Console.WriteLine(item.Family + " " + item.OrderID );

:‫ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬C# 3.0 ‫ﻣﻌﺪﻝ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮﻱ ﺑﺎﻻ ﺑﻮﺳﻴﻠﻪ ﻋﺒﺎﺭﺍﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﺩﺭ‬

var query = from c in customers


where c.Family == "Aghdam"
from o in c.Orders
where o.OrderDate.Year > 2010
select new { c.Name, o.OrderID };

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


ArgumentNullExceptio ‫ ﻣﻘﺪﺍﺭ ﺩﻫﻲ ﺷﻮﻧﺪ ﻳﮏ ﺍﺳﺘﺜﻨﺎﺀ‬null ‫ ﺑﺎ‬SelectMany ‫ﺍﮔﺮ ﻫﺮ ﻳﮏ ﺍﺯ ﺁﺭﮔﻮﻣﺎﻥ ﻫﺎﻱ ﻋﻤﻠﮕﺮ‬
.‫ﺗﻮﻟﻴﺪ ﺧﻮﺍﻫﺪ ﺷﺪ‬
‫|ﺻﻔﺤﻪ‪30‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺗﺼﺎﻝ ‪Join Operators‬‬


‫ﮎ ﺩﺍﺭﺍﻱ ﺍﺷﺘﺮﺍﮐﺎﺗﻲ ﻫﺴﺘﻨﺪ‪ ،‬ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‪ .‬ﻋﻤﻠﮕﺮﻫﺎﻱ‬
‫ﺍﻳﻦ ﻧﻮﻉ ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﻣﺘﺤﺪ ﮐﺮﺩﻥ ﭼﻨﺪ ﻣﺠﻤﻮﻋﻪ ﻋﻨﺎﺻﺮ ﻩ‬
‫ﺍﺗﺼﺎﻝ ﺩﺭ ‪ LINQ‬ﺩﻗﻴﻘﺎ ﻫﻤﺎﻧﻨﺪ ﻣﺎﺩﻩ ﻫﺎﻱ ﺍﺗﺼﺎﻝ ﺩﺭ ‪ SQL‬ﻋﻤﻞ ﻣﻲ ﮐﻨﻨﺪ‪ .‬ﻫﺮ ﻣﺠﻤﻮﻋﻪ ﻋﻨﺼﺮ ﻭ ﻳﺎ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﻭﻳﮋﮔﻲ ﻫﺎﻱ‬
‫ﮐﻠﻴﺪﻱ ﺭﺍ ﺩﺍﺭﺍ ﻣﻲ ﺑﺎﺷﺪ ﮐﻪ ﺑﻮﺳﻴﻠﻪ ﺁﻧﻬﺎ ﻣﻲ ﺗﻮﺍﻥ ﺩﺍﺩﻩ ﻫﺎ ﺭﺍ ﻣﻘﺎﻳﺴﻪ ﻭ ﺟﻤﻊ ﺁﻭﺭﻱ ﻧﻤﻮﺩ‪.‬‬

‫ﻋﻤﻠﮕﺮ ‪Join‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ‪ INNER Join‬ﺩﺭ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻫﺎﻱ ﺭﺍﺑﻄﻪ ﺍﻱ ﻋﻤﻞ ﻣﻲ ﮐﻨﺪ ﻳﻌﻨﻲ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﮐﻠﻴﺪﻫﺎﻱ‬
‫ﮐﻪ ﺩﺭ ﻫﺮ ﺩﻭ ﻣﺮﺗﺒﻂ ﻫﺴﺘﻨﺪ ﻭ ﺑﻪ ﻋﻨﻮﺍﻥ ﺁﺭﮔﻮﻣﺎﻥ ﺑﻪ ﺁﻥ ﺍﺭﺳﺎﻝ ﻣﻲ ﮔﺮﺩ ﻥﺩ‪ ،‬ﺗﺮﮐﻴﺐ ﻣﻲ ﮐﻨﺪ‪ .‬ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﻓﺮﻡ ﺯﻳﺮ‬
‫ﺍﺳﺖ)ﺑﺪﻭﻥ ﺳﺮﺑﺎﺭﮔﺬﺍﺭﻱ(‪:‬‬

‫(>‪public static IEnumerable<V> Join<T, U, K, V‬‬


‫‪this IEnumerable<T> outer,‬‬
‫‪IEnumerable<U> inner,‬‬
‫‪Func<T, K> outerKeySelector,‬‬
‫‪Func<U, K> innerKeySelector,‬‬
‫;)‪Func<T, U, V> resultSelector‬‬

‫ﭘﺎﺭﺍﻣﺘﺮ ‪ Outer‬ﻧﺸﺎﻥ ﺩﻫﻨﺪﻩ ﻧﻮﻉ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺧﺎﺭﺟﻲ ﻭ ﭘﺎﺭﺍﻣﺘﺮ ‪ inner‬ﻧﺸﺎﻥ ﺩﻫﻨﺪﻩ ﻧﻮﻉ ﻣﻨﺒﻊ ﺩﺍﺩﻩ ﺩﺍﺧﻠﻲ ﺍﺳﺖ ‪.‬‬
‫‪ inner‬ﻭ ‪outer‬‬ ‫ﭘﺎﺭﺍﻣﺘﺮﻫﺎﻱ ‪ outerKeySelector‬ﻭ ‪ innerKeySelector‬ﺗﻌﻴﻴﻦ ﻣﻲ ﮐﻨﻨﺪ ﮐﻪ ﺩﺍﺩﻩ ﻫﺎ ﭼﻄﻮﺭ ﺍﺯ ﻣﻨﺎﺑﻊ‬
‫‪ Join‬ﺭﺍ ﭘﺪﻳﺪ ﻣﻲ ﺁﻭﺭﺩ‪ .‬ﺗﺎﺑﻊ‬ ‫ﺍﺳﺘﺨﺮﺍﺝ ﮔﺮﺩﻧﺪ‪ .‬ﻧﻮﻉ ﺩﻭﻡ ﻫﺮﺩﻭ ﺁﻧﻬﺎ ﺍﺯ ﻧﻮﻉ ‪ K‬ﻣﻲ ﺑﺎﺷﻨﺪ ﮐﻪ ﺗﻌﺎﺩﻝ ﻣﻴﺎﻥ ﺍﻳﻦ ﺩﻭ‪ ،‬ﺷﺮﻁ‬
‫‪ resultSelector‬ﮐﻪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺁﺧﺮﻳﻦ ﭘﺎﺭﺍﻣﺘﺮ ﺗﻌﻴﻴﻦ ﺷﺪﻩ ﺍﺳﺖ ﺑﺮﺍﻱ ﺟﻔﺖ ﻋﻨﺎﺻﺮ ﺩﺍﺧﻠﻲ ﻭ ﺧﺎﺭﺟﻲ )ﺗﻄﺎﺑﻖ ﺩﺍﺩﻩ ﺷﺪﻩ(‬
‫ﺑﺮﺭﺳﻲ ﺷﺪﻩ ﻭ ﺷﺊ ﻧﺘﻴﺠﻪ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ‪.‬‬
‫ﻋﻤﻠﮕﺮ ‪ Join‬ﺗﺮﺗﻴﺐ ﻋﻨﺎﺻﺮ ﺧﺎﺭﺟﻲ ﺭﺍ ﺣﻔﻂ ﻣﻴﮑﻨﺪ ﻭ ﻫﻤﭽﻨﻴﻦ ﺑﺮﺍﻱ ﻫﺮ ﻋﻨﺼﺮ ﺧﺎﺭﺟﻲ‪ ،‬ﺗﺮﺗﻴﺐ ﻋﻨﺎﺻﺮ ﺗﻄﺒﻴﻖ ﺩﺍﺩﻩ ﺷﺪﻩ‬
‫ﺩﺍﺧﻠﻲ ﺭﺍ ﻧﻴﺰ ﺣﻔﻆ ﻣﻴﮑﻨﺪ‪.‬‬
‫ﺩﺭ ﭘﺎﻳﮕﺎﻩ ﺩﺍﺩﻩ ﻫﺎﻱ ﺭﺍﺑﻄﻪ ﺍﻱ ﻋﻤﻠﮕﺮﻫﺎﻱ ‪ Join‬ﺩﻳﮕﺮﻱ ﻫﻤﺎﻧﻨﺪ ‪ left outer joins‬ﻭﺟﻮﺩ ﺩﺍﺭﺩ ﻭﻟﻲ ﺍﻳﻦ ﻧﻮﻉ ﺍﺗﺼﺎﻻﺕ ﺑﻪ‬
‫ﺻﻮﺭﺕ ﺻﺮﻳﺢ ﺩﺭ ‪ LINQ‬ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻧﺸﺪﻩ ﻭﻟﻲ ﺩﺭ ﺯﻳﺮ ﻣﺠﻤﻮﻋﻪ ﻗﺎﺑﻠﻴﺖ ﻫﺎﻱ ﻋﻤﻠﮕﺮ ‪ GroupJoin‬ﻗﺮﺍﺭ ﺩﺍﺭﻧﺪ‪.‬‬

‫ﻣﺜﺎﻝ ‪ :‬ﺩﺭ ﺑﺮﻧﺎﻣﻪ ﺯﻳﺮ ﺍﺷﻴﺎﺀ ‪ Customer‬ﻭ ‪ Order‬ﺑﺎ ﺗﻮﺟﻪ ﺑﻪ ﻣﻘﺪﺍﺭ ‪ CustomerID‬ﺑﻪ ﻫﻢ ﺩﻳﮕﺮ ﻣﺘﺼﻞ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﺩﺭ‬
‫ﺧﺮﻭﺟﻲ ﺷﺊ ﺩﺍﺭﻳﻢ ﮐﻪ ﺷﺎﻣﻞ ﺍﻃﻼﻋﺎﺗﻲ ﺗﺮﮐﻴﺐ ﺷﺪﻩ ﺍﺯ ﺍﻳﻦ ﺩﻭ ﺷﺊ ﺍﺳﺖ‪.‬‬

‫)(>‪List<Customer> customers = new List<Customer‬‬


‫{‬
‫"‪new Customer() {Name ="Ali‬‬ ‫‪, Family = "Aghdam" , CustomerID =0 },‬‬
‫"‪new Customer() {Name ="Ali‬‬ ‫‪, Family = "Nasiri" , CustomerID =1 },‬‬
‫} ‪new Customer() {Name ="Arash" , Family = "Novin" , CustomerID =2‬‬
‫;}‬
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬31 ‫ﺻﻔﺤﻪ‬

List<Order> orders = new List<Order>() {


new Order(){CustomerID = 0, OrderID = 1,OrderDate = new DateTime(2010,1,1)} ,
new Order(){CustomerID = 1, OrderID = 2,OrderDate = new DateTime(2011,1,1)}
};

var query =
from c in customers
join o in orders on c.CustomerID equals o.CustomerID
select new {FullName = c.Name + " " +
c.Family ,
c.CustomerID ,
o.OrderDate ,
TotalOrder = o.Total
};

foreach (var item in query)


Console.WriteLine(item.FullName +
" ,ID= " + item.CustomerID +
" ,Order Date= " + item.OrderDate +
" ,Total Order="+ item.TotalOrder );

:‫ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬C# 3.0 ‫ﻣﻌﺎﺩﻝ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮﻱ ﺑﺎﻻ ﺑﻮﺳﻴﻠﻪ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﺩﺭ‬

var query =customers.Join(


orders,
c => c.CustomerID,
o => o.CustomerID,
(c, o) => new { FullName = c.Name + " " + c.Family ,
o.OrderDate,
TotalOrder = o.Total,
c.CustomerID }
);
32‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

GroupJoin ‫ﻋﻤﻠﮕﺮ‬
‫ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺍﺭﺍﻱ ﺩﻭ‬. left outer joins ‫ ﻫﻤﺎﻧﻨﺪ‬،‫ ﻫﺎ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ‬Join ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺍﻱ ﺍﻧﻮﺍﻉ ﺧﺎﺻﻲ ﺍﺯ‬
:‫ﺳﺮﺑﺎﺭ ﮔﺬﺍﺭﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static IEnumerable<TResult>


GroupJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, IEnumerable<TInner>, TResult> resultSelector);

public static IEnumerable<TResult>


GroupJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
IEqualityComparer<TKey> comparer);

‫ ﺭﺍ ﺩﺭ ﻗﺎﻟﺐ ﻳﮏ ﻣﺠﻤﻮﻋﻪ‬join ‫ ﻋﻤﻞ ﻣﻲ ﮐﻨﺪ ﻭﻟﻲ ﺑﺎ ﺍﻳﻦ ﺗﻔﺎﻭﺕ ﮐﻪ ﻧﺘﻴﺠﻪ ﻋﻤﻠﻴﺎﺕ‬Join ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ‬
.‫ﺟﺪﻳﺪ ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ‬
. ‫ﻣﺜﺎﻝ‬

List<Customer> customers = new List<Customer>()


{
new Customer() {Name ="Ali" , Family = "Aghdam" , CustomerID =0 },
new Customer() {Name ="Ali" , Family = "Nasiri" , CustomerID =1 },
new Customer() {Name ="Arash" , Family = "Novin" , CustomerID =2 },
new Customer() {Name ="Arash" , Family = "Novin" , CustomerID =3 }
};
List<Order> orders = new List<Order>() {
new Order(){CustomerID = 0,OrderID =0},
new Order(){CustomerID = 1,OrderID =1},
new Order(){CustomerID = 2,OrderID =2},
new Order(){CustomerID = 1,OrderID =3},
new Order(){CustomerID = 0,OrderID =4},
};

var query = from c in customers


join o in orders on c.CustomerID equals o.CustomerID into q1
select new { CustomerName = c.Family, orders = q1 };

foreach (var item in query)


{
Console.WriteLine(item.CustomerName + ", Orders = ");
foreach (var order in item.orders)
Console.WriteLine("\t order ID={0}", order.OrderID);
}
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬33 ‫ﺻﻔﺤﻪ‬

Grouping Operators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺩﺳﺘﻪ ﺑﻨﺪﻱ‬


.‫ﺍﻳﻦ ﻧﻮﻉ ﻋﻤﻠﮕﺮ ﻫﺎ ﺑﺮﺍﻱ ﺩﺳﺘﻪ ﺑﻨﺪﻱ ﻋﻨﺎﺻﺮ ﺑﺴﺘﻪ ﺑﻪ ﻳﮏ ﮐﻠﻴﺪ ﺩﺭﻭﻧﻲ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﻧﺪ‬

Group By ‫ﻋﻤﻠﮕﺮ‬
.‫ﺑﻮﺳﻴﻠﻪ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻲ ﺗﻮﺍﻥ ﻋﻨﺎﺻﺮﻱ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﻧﺘﻴﺠﻪ ﺭﺍ ﺑﻮﺳﻴﻠﻪ ﻳﮏ ﺷﺮﻁ ﺧﺎﺹ )ﺗﺎﺑﻊ ﮔﺰﻳﻨﺸﻲ( ﺩﺳﺘﻪ ﺑﻨﺪﻱ ﮐﺮﺩ‬
.‫ ﺍﺳﺖ‬SQL ‫ ﺩﺭ‬Group By ‫ ﺩﻗﻴﻘﺎ ﻣﺸﺎﺑﻪ ﻣﺎﺩﻩ‬LINQ ‫ ﺩﺭ‬Group by ‫ﻋﻤﻠﮑﺮﺩ ﻋﻤﻠﮕﺮ ﺩﺳﺘﻪ ﺑﻨﺪﻱ‬

‫ ﺳﺮﺑﺎﺭﮔﺬﺍﺭﻱ ﺍﻭﻝ ﺍﻳﻦ‬4 ‫ ﺩﺭ ﺯﻳﺮ‬،‫ ﻧﻮﻉ ﺳﺮﺑﺎﺭﮔﺬﺍﺭﻱ ﺍﺳﺖ‬8 ‫ ﺗﻨﻬﺎ ﻋﻤﻠﮕﺮ ﺩﺭ ﺍﻳﻦ ﮔﺮﻭﻩ ﻣﻲ ﺑﺎﺷﺪ ﮐﻪ ﺷﺎﻣﻞ‬Group By ‫ﻋﻤﻠﮕﺮ‬
.‫ﻋﻤﻠﮕﺮ ﺁﻣﺪﻩ ﺍﺳﺖ‬

public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(


this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);

public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(


this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
IEqualityComparer<TKey> comparer);

public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey,


TElement>(
this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector);

public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey,


TElement>(
this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector,
IEqualityComparer<TKey> comparer);

‫ ﺑﺮﺍﻱ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ‬IEnumerable<IGrouping<TKey, TElement >>‫ ﻳﮏ ﻧﻮﻉ ﺍﺯ‬،‫ﺩﺭ ﺑﺎﺭﮔﺬﺍﺭﻱ ﻫﺎﻱ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‬
‫ ﻧﺤﻮﻩ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺍﻳﻦ ﺭﺍﺑﻂ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ‬.‫ ﻓﺮﺍﻫﻢ ﮐﺮﺩﻩ ﺍﺳﺖ‬Key ‫ﻣﻲ ﮔﺮﺩﺩ ﮐﻪ ﺩﺭ ﺧﻮﺩ ﻳﮏ ﺧﺼﻮﺻﻴﺖ ﻓﻘﻂ ﺧﻮﺍﻧﺪﻧﻲ‬
.‫ﺍﺳﺖ‬

public interface IGrouping<TKey, TElement> : IEnumerable<TElement> {


TKey Key { get; }
}

‫ ﺑﻮﺳﻴﻠﻪ ﺍﺭﺯﻳﺎﺑﻲ ﻭ ﺷﻤﺎﺭﺵ ﭘﺎﺭﺍﻣﺘﺮ‬source ‫ ﭘﺎﺭﺍﻣﺘﺮ ﺍﻭﻝ ﺗﺎﺑﻊ ﻳﻌﻨﻲ‬Group by ‫ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍﻱ ﭘﺮﺱ ﻭ ﺟﻮ ﺣﺎﻭﻱ ﻋﻤﻠﮕﺮ‬
>> ‫ ﺗﻌﻴﻴﻦ ﻣﻲ ﮔﺮﺩﺩ ﻭ ﺧﺮﻭﺟﻲ ﺩﺭ ﻳﮏ ﻧﻤﻮﻧﻪ ﺍﺯ‬elementSelector ‫ ﻭ‬keySelector ‫ﻫﺎﻱ‬
‫ ﺁﻥ ﺑﺮﺍﻱ ﻧﻤﺎﻳﺶ ﺩﺍﺩﻥ‬Key ‫ ﺩﺭﺝ ﻣﻲ ﺷﻮﺩ ﮐﻪ ﺧﺼﻮﺻﻴﺖ ﻓﻘﻂ ﺧﻮﺍﻧﺪﻧﻲ‬IEnumerable<IGrouping<TKey, TElement

.‫ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ‬،‫ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ‬group by ‫ ﺩﺭ ﻋﻤﻠﮕﺮ‬by ‫ﻓﻴﻠﺪﻱ ﺟﻠﻮﻱ ﻗﺴﻤﺖ‬
34‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

.‫ ﺩﺭ ﺍﻳﻦ ﻣﺜﺎﻝ ﻣﺸﺘﺮﻳﺎﻥ ﺑﺮ ﺍﺳﺎﺱ ﮐﺸﻮﺭﺷﺎﻥ ﺩﺳﺘﻪ ﺑﻨﺪﻱ ﻣﻲ ﺷﻮﻧﺪ‬:1‫ﻣﺜﺎﻝ‬

List<Customer> customers = new List<Customer>()


{
new Customer() {Name ="Ali" , Family = "Aghdam" , Country = "iran" ,
CustomerID =0 },
new Customer() {Name ="Ali" , Family = "Nasiri" , Country = "england"
, CustomerID =1 },
new Customer() {Name ="Arash" , Family = "Novin" , Country = "india" ,
CustomerID =2 },
new Customer() {Name ="Arash" , Family = "Novin" , Country = "iran" ,
CustomerID =3 }
};

var query = from c in customers


group c by c.Country;

foreach (var CountryGroup in query)


{
Console.WriteLine( CountryGroup.Key);
foreach (var customerInGroup in CountryGroup)
{
Console.WriteLine(customerInGroup);
}
}

.2 ‫ﻣﺜﺎﻝ‬

var query = from c in customers


group c by c.Country into cc
select new { Country = cc.Key };

foreach (var item in query)


{
Console.WriteLine( item.Country);
}

cc ‫ﺩﺭ ﺍﻳﻦ ﻣﺜﺎﻝ ﻣﺸﺘﺮﻳﺎﻥ ﺑﺮ ﺍﺳﺎﺱ ﮐﺸﻮﺭﺷﺎﻥ ﺩﺳﺘﻪ ﺑﻨﺪﻱ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﻭ ﺩﺭ ﻧﺘﻴﺠﻪ ﺍﻳﻦ ﺩﺳﺘﻪ ﺑﻨﺪﻱ ﺩﺭ ﺩﺭﻭﻥ ﻣﺘﻐﻴﺮ‬
‫ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﭘﺮﺱ ﻭ ﺟﻮ ﺍﻧﺘﺨﺎﺏ ﻣﻲ‬cc ‫ ﻣﺮﺑﻮﻁ ﺑﻪ‬key ‫ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ ﻭ ﺳﭙﺲ ﮔﺮﻭﻩ ﮐﺸﻮﺭﻫﺎ ﺑﺮ ﺍﺳﺎﺱ ﺧﺼﻮﺻﻴﺖ‬
.‫ﺷﻮﻧﺪ‬
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬35 ‫ﺻﻔﺤﻪ‬

‫ ﻧﻤﺎﻳﺶ ﺗﻌﺪﺍﺩ ﻣﺸﺘﺮﻳﺎﻥ ﺍﺯ ﻫﺮ ﺩﺳﺘﻪ ﮐﺸﻮﺭ‬:3 ‫ﻣﺜﺎﻝ‬


var query = from c in customers
group c by c.Country into cc
select new { Cuntry = cc.Key , Count = cc.Count() };

foreach (var item in query)


{
Console.WriteLine(item.Count + " Customer from " + item.Cuntry);
}

Ordering Operators - ‫ﻋﻤﻠﮕﺮ ﻫﺎﻱ ﻣﺮﺗﺐ ﺳﺎﺯﻱ‬


.‫ﻋﻤﻠﮕﺮ ﻫﺎﻱ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺑﺮﺍﻱ ﺗﻨﻈﻴﻢ ﺟﺎﻳﮕﺎﻩ ﻫﺮ ﻋﻨﺼﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﻭ ﻧﺤﻮﻩ ﭼﻴﺪﻣﺎﻥ ﺁﻧﻬﺎ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ‬

OrderBy ‫ﻋﻤﻠﮕﺮ‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﮐﻠﻴﺪ ﺑﻪ ﺻﻮﺭﺕ ﺻﻌﻮﺩﻱ ﻣﺮﺗﺐ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﻋﻤﻠﮑﺮﺩﻱ ﻣﺎﻧﻨﺪ ﻣﺎﺩﻩ‬
.‫ ﺩﺍﺭﺩ‬Order By

.‫ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector);

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IComparer<TKey> comparer);

‫ ﺑﺮﺍﻱ ﺗﻌﻴﻴﻦ ﻓﻴﻠﺪﻱ ﮐﻪ ﻋﻤﻠﻴﺎﺕ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺑﺮ ﺍﺳﺎﺱ ﺁﻥ ﺑﺮ ﺭﻭﻱ‬keySelector ‫ﺩﺭ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﭘﺮﺍﻣﺘﺮ‬
‫ ﻣﻲ ﺗﻮﺍﻥ ﺑﺮﺍﻱ‬compare ‫ ﺩﺭ ﻓﺮﻡ )ﺑﺎﺭﮔﺰﺍﺭﻱ( ﺩﻭﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﺯ ﭘﺎﺭﺍﻣﺘﺮ‬.‫ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‬،‫ ﺻﻮﺭﺕ ﻣﻲ ﮔﻴﺮﺩ‬source
‫ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍﻱ ﺑﺮﻧﺎﻣﻪ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﭘﺮﺍﻣﺘﺮ‬.‫ﻋﻤﻠﻴﺎﺕ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺳﻔﺎﺭﺷﻲ ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ‬
.‫ ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‬IOrderedEnumerable<TSource> ‫ ﺍﺭﺯﻳﺎﺑﻲ ﻣﻲ ﻧﻤﺎﻳﺪ ﻭ ﻳﮏ ﻧﻤﻮﻧﻪ ﺍﺯ ﻧﻮﻉ‬keySelector

.‫ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺑﻪ ﺻﻮﺭﺕ ﺻﻌﻮﺩﻱ ﺑﺮ ﺍﺳﺎﺱ ﻧﺎﻡ ﻭ ﻧﺎﻡ ﻓﺎﻣﻴﻠﻲ ﻣﺸﺘﺮﻱ‬.1‫ﻣﺜﺎﻝ‬


List<Customer> customers = new List<Customer>()
{
new Customer() {Name ="Ali" , Family = "Aghdam" , Country = "iran" ,
CustomerID =0 },
new Customer() {Name ="Ali" , Family = "Nasiri" , Country = "england"
, CustomerID =1 },
36‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

new Customer() {Name ="Arash" , Family = "Novin" , Country = "india" ,


CustomerID =2 },
new Customer() {Name ="Ali" , Family = "Novin" , Country = "iran" ,
CustomerID =3 }
};

var query = from c in customers


orderby c.Family
select c;

foreach (var item in query)


Console.WriteLine(item);

OrderBy descending ‫ﻋﻤﻠﮕﺮ‬


‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﮐﻠﻴﺪ ﺑﻪ ﺻﻮﺭﺕ ﻧﺰﻭﻟﻲ ﻣﺮﺗﺐ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﻋﻤﻠﮑﺮﺩﻱ ﻣﺎﻧﻨﺪ ﻣﺎﺩﻩ‬
.‫ ﺩﺍﺭﺩ‬Order By

public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector);

public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IComparer<TKey> comparer);

‫ ﺑﺮﺍﻱ ﺗﻌﻴﻴﻦ ﻓﻴﻠﺪﻱ ﮐﻪ ﻋﻤﻠﻴﺎﺕ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺑﺮ ﺍﺳﺎﺱ ﺁﻥ ﺑﺮ ﺭﻭﻱ‬keySelector ‫ﺩﺭ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﭘﺮﺍﻣﺘﺮ‬
‫ ﻣﻲ ﺗﻮﺍﻥ ﺑﺮﺍﻱ‬compare ‫ ﺩﺭ ﻓﺮﻡ )ﺑﺎﺭﮔﺰﺍﺭﻱ( ﺩﻭﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﺯ ﭘﺎﺭﺍﻣﺘﺮ‬.‫ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‬،‫ ﺻﻮﺭﺕ ﻣﻲ ﮔﻴﺮﺩ‬source
‫ ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍﻱ ﺑﺮﻧﺎﻣﻪ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬OrderBy ‫ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ‬.‫ﻋﻤﻠﻴﺎﺕ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺳﻔﺎﺭﺷﻲ ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ‬
‫ ﺭﺍ ﺑﺮﻣﻲ‬IOrderedEnumerable<TSource> ‫ ﺍﺭﺯﻳﺎﺑﻲ ﻣﻲ ﻧﻤﺎﻳﺪ ﻭ ﻳﮏ ﻧﻤﻮﻧﻪ ﺍﺯ ﻧﻮﻉ‬keySelector ‫ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﭘﺮﺍﻣﺘﺮ‬
.‫ﮔﺮﺩﺍﻧﺪ‬

.‫ ﺑﻪ ﺻﻮﺭﺕ ﻧﺰﻭﻟﻲ‬OrderBy ‫ ﺩﺭ ﻋﻤﻠﮕﺮ‬1‫ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮ ﻣﺜﺎﻝ‬.‫ﻣﺜﺎﻝ‬

var query = from c in customers


orderby c.Family descending
select c;
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 37‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻋﻤﻠﮕﺮ ‪Thenby‬‬
‫ﻋﻤﻠﮑﺮ ‪ OrderBy‬ﺍﻳﻦ ﻋﻤﻠﻴﺎﺕ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻳﮏ ﮐﻠﻴﺪ ﺭﺍ ﺍﻣﺎﮐﻦ ﭘﺬﻳﺮ ﻣﻲ ﻧﻤﻮﺩ ﻭﻟﻲ ﺑﺮﺍﻱ ﺍﻳﻨﮑﻪ ﺑﺘﻮﺍﻥ ﺍﺯ‬
‫ﻋﻤﻠﻴﺎﺕ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺑﻪ ﺻﻮﺭﺕ ﺻﻌﻮﺩﻱ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﭼﻨﺪ ﮐﻠﻴﺪ ﺍﻧﺠﺎﻡ ﺩﺍﺩ‪ ،‬ﻣﻲ ﺑﺎﻳﺴﺖ ﺍﺯ ﻋﻤﻠﮕﺮ ‪ ThenBy‬ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‪.‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺍﺭﺍﻱ ﺩﻭ ﺳﺮﺑﺎﺭﮔﺬﺍﺭﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪.‬‬

‫(>‪public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey‬‬


‫‪this IOrderedEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, TKey> keySelector‬‬

‫(>‪public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey‬‬


‫‪this IOrderedEnumerable<TSource> source,‬‬
‫‪Func<TSource, TKey> keySelector,‬‬
‫;)‪IComparer<TKey> comparer‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ ‪ OrderBy‬ﻣﻌﻤﻮﻝ ﺍﺳﺖ ﺗﻨﻬﺎ ﺑﺎ ﺍﻳﻦ ﺗﻔﺎﻭﺕ ﮐﻪ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻲ ﺗﻮﺍﻧﺪ ﺗﻨﻬﺎ ﺑﺮ ﺭﻭﻱ ﻧﻮﻉ‬
‫>‪ IOrderedEnumerable<TSource‬ﻋﻤﻠﻴﺎﺕ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺭﺍ ﺍﻧﺠﺎﻡ ﺩﺍﺩ ﮐﻪ ﺑﺪﻳﻦ ﻭﺳﻴﻠﻪ ﻣﻲ ﺑﺎﻳﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺭﺍ ﺑﻌﺪ ﺍﺯ‬
‫ﻋﻤﻠﮕﺮ ‪ OrderBy‬ﻭ ﻳﺎ ‪ Orderby Descending‬ﻭ ﻳﺎ ‪ Thenby Descending‬ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‪.‬‬
‫ﺍﻟﺒﺘﻪ ﺩﺭ ﺯﻣﺎﻥ ﻧﻮﺷﺘﻦ ﭘﺮﺱ ﻭ ﺟﻮﻫﺎ ﺑﻪ ﺻﻮﺭﺕ ﻋﺒﺎﺭﺕ ﻫﺎﻱ ﭘﺮﺱ ﻭ ﺟﻮﻱ ‪ LINQ‬ﺍﺯ ﻋﻤﻠﮕﺮ ‪ OrderBy‬ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‬
‫ﻭ ﮐﻠﻴﺪﻫﺎ ﺑﻮﺳﻴﻪ ﮐﺎﻣﺎ ) ¡ ( ﺍﺯ ﻳﮑﺪﻳﮕﺮ ﺟﺪﺍ ﮐﺎﻣﭙﺎﻳﻞ ﺷﺪﻥ ﭘﺮﺱ ﻭ ﺟﻮ ﻫﺎ ﮐﺎﻣﭙﺎﻳﻠﺮ ﺧﻮﺩ ﺍﻳﻦ ﻣﻮﺭﺩ ﺭﺍ ﻣﺘﻮﺟﻪ ﺷﺪﻩ ﻭ ﻋﺒﺎﺭﺕ‬
‫ﻣﺘﺪﻱ ﺁﻥ ﺭﺍ ﺗﻨﻈﻴﻢ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﺑﻪ ﻃﻮﺭ ﻣﺜﺎﻝ ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮﻱ ﺯﻳﺮ ﺭﺍ ﺩﺭ ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ‪.‬‬

‫‪var query = from c in customers‬‬


‫‪orderby c.Name , c.Family‬‬
‫;‪select c‬‬

‫ﺍﻳﻦ ﭘﺮﺱ ﻭ ﺟﻮ ﺩﺭ ﻫﻨﮕﺎﻡ ﮐﺎﻣﭙﺎﻳﻞ ﺑﻪ ﺻﻮﺭﺕ ﻣﺘﺪﻱ ﺯﻳﺮ ﺗﺒﺪﻳﻞ ﻣﻲ ﮔﺮﺩﺩ‪.‬‬

‫)‪var query = customers.OrderBy(c => c.Name‬‬


‫;)‪.ThenBy(c => c.Family‬‬

‫ﻫﻤﺎﻧﻄﻮﺭ ﮐﻪ ﺩﺭ ﻋﺒﺎﺭﺕ ﺑﺎﻻ ﻣﺸﺎﻫﺪﻩ ﻣﻲ ﮐﻨﻴﺪ ﻋﻤﻠﮕﺮ ‪ ThenBy‬ﺩﺭ ﺻﻮﺭﺕ ﻣﺘﺪﻱ ﺧﻮﺩ ﻧﻮﺷﺘﻪ ﻣﻲ ﺷﻮﺩ ﻭ ﺩﺭ ﻧﻮﻉ "ﻋﺒﺎﺭﺕ‬
‫ﭘﺮﺱ ﻭ ﺟﻮ" ﺍﺯ ﻫﻤﺎﻥ ﻋﻤﻠﮕﺮ ‪ OrderBy‬ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ ﻭ ﮐﻠﻴﺪﻫﺎ ﺑﺎ ﮐﺎﻣﺎ ﺍﺯ ﻳﮑﺪﻳﮕﺮ ﺟﺪﺍ ﻣﻲ ﺷﻮﻧﺪ‪ .‬ﺑﺮﺍﻱ ﮐﺎﻣﭙﺎﺳﻞ ﺷﺪﻥ‬
38‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

‫ ﺩﺭ ﺍﺑﺘﺪﺍﻱ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﻭﺟﻮﺩ‬OrderBy ‫ﻋﺒﺎﺭﺍﺕ ﻣﻲ ﺗﻮﺍﻥ ﺗﺮﺗﻴﺐ ﺯﻳﺮ ﺭﺍ ﻧﻮﺷﺖ ﮐﻪ ﺩﺭ ﻫﺮ ﺻﻮﺭﺕ ﻣﻲ ﺑﺎﻳﺴﺖ ﻳﮏ ﻋﻤﻠﮕﺮ‬
.‫ ﺗﻬﻴﻪ ﺷﻮﺩ ﺗﺎ ﻋﻤﻠﮕﺮ ﻫﺎﻱ ﺩﻳﮕﺮ ﺑﺮ ﺭﻭﻱ ﺁﻥ ﻋﻤﻞ ﮐﻨﻨﺪ‬IOrderedEnumerable<TSource> ‫ﺩﺍﺷﺘﻪ ﺑﺎﺷﺪ ﺗﺎ ﻳﮏ ﻧﻮﻉ‬

Source . OrderBy . ThenBy . ThenBy …

ThenByDecending ‫ﻋﻤﻠﮕﺮ‬
‫ ﺩﺍﺭﺩ ﻭ ﺗﻨﻬﺎ ﺗﻔﺎﻭﺕ ﺁﻧﻬﺎ ﺩﺭ ﺍﻳﻦ ﺍﺳﺖ ﮐﻪ ﺍﻳﻦ ﺗﺎﺑﻊ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ‬Thenby ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﮐﺎﺭﮐﺮﺩﻱ ﺩﻗﻴﻘﺎ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ‬
.‫ ﺍﻳﻦ ﺗﺎﺑﻊ ﺩﺍﺭﺍﻱ ﺩﻭ ﺳﺮﺑﺎﺯﮔﺬﺍﺭﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬.‫ﺻﻮﺭﺕ ﻧﺰﻭﻟﻲ ﻣﺮﺗﺐ ﻣﻲ ﮐﻨﺪ‬

public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(


this IOrderedEnumerable<TSource> source,
Func<TSource, TKey> keySelector);

public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(


this IOrderedEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IComparer<TKey> comparer);

‫ ﻋﻤﻞ ﮐﻨﺪ ﮐﻪ‬IOrderedEnumerable<TSource> ‫ ﺑﺮ ﺭﻭﻱ ﻣﺠﻤﻮﻋﻪ ﺍﻱ ﺍﺯ ﻧﻮﻉ‬ThenBy ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ‬
‫ ﺍﺳﺘﻔﺎﺩﻩ ﺷﻮﺩ ﻭ ﺩﺭ ﻧﻮﺷﺘﺎﺭ‬ThenBy ‫ ﻭ ﻳﺎ‬OrderByDescending ¡ OrderBy ‫ﺑﻪ ﻫﻤﻴﻦ ﺩﻟﻴﻞ ﻣﻲ ﺑﺎﻳﺴﺖ ﺑﻌﺪ ﺍﺯ ﻋﻤﻠﮕﺮﻫﺎﻱ‬
‫ ﺭﺍ ﻣﻘﺎﺑﻞ ﮐﻠﻴﺪ ﻧﻮﺷﺖ ﻭ ﺩﺭ ﻧﻮﻉ ﻣﺘﺪﻱ ﻣﻲ ﺑﺎﻳﺴﺖ ﺑﻪ ﺻﻮﺭﺕ ﻣﺴﺘﻘﻴﻢ‬Descending ‫"ﻋﺒﺎﺭﺕ ﭘﺮﺱ ﻭ ﺟﻮ" ﻣﻲ ﺑﺎﻳﺴﺖ ﮐﻠﻤﻪ‬
.‫ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‬ThenByDescending ‫ﺍﺯ ﻣﺘﺪ‬

.‫ﻣﺜﺎﻝ‬

var query = from c in customers


orderby c.Name, c.Family descending
select c;

: ‫ﻣﻌﺎﺩﻝ ﺑﺎ ﺻﻮﺭﺕ ﻣﺘﺪﻱ ﺯﻳﺮ‬

var query = customers.OrderBy(c => c.Name)


.ThenByDescending(c => c.Family);
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬39 ‫ﺻﻔﺤﻪ‬

Reverse ‫ﻋﻤﻠﮕﺮ‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﻤﺎﻧﻨﺪ ﻧﺎﻡ ﺧﻮﺩ ﺑﺮﺍﻱ ﻭﺍﺭﻭﻥ ﮐﺮﺩﻥ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺑﻪ ﮐﺎﺭ ﻣﻲ ﺭﻭﺩ ﻳﻌﻨﻲ ﻋﻨﺎﺻﺮ ﭼﻴﻨﺶ ﻋﻨﺎﺻﺮ ﻧﺘﻴﺠﻪ ﺭﺍ‬
.‫ﺑﺮﻋﮑﺲ ﻣﻲ ﮐﻨﺪ ﻭ ﻓﻘﻂ ﺩﺍﺭﺍﻱ ﻳﮏ ﺑﺎﺭﮔﺰﺍﺭﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static IEnumerable<TSource> Reverse<TSource>(


this IEnumerable<TSource> source);

‫ ﺍﻣﺎ‬IEnumerable<T> ‫ﮐﺎﺭﮐﺮﺩ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺴﻴﺎﺭ ﺳﺎﺩﻩ ﺍﺳﺖ ﻭ ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺩﺭ ﻳﮏ ﻧﻤﻮﻧﻪ ﺟﺪﻳﺪ ﺍﺯ‬
.‫ﺑﻪ ﺻﻮﺭﺕ ﻋﮑﺲ ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ‬

‫ ﺩﺭ ﺍﻳﻦ ﻣﺜﺎﻝ ﻣﺮﺗﺐ ﺳﺎﺯﻱ ﺑﻪ ﺻﻮﺭﺕ ﺻﻌﻮﺩﻱ ﺑﺮ ﺍﺳﺎﺱ ﻧﺎﻡ ﻣﺸﺘﺮﻱ ﺻﻮﺭﺕ ﻣﻲ ﮔﻴﺮﺩ ﻭ ﺳﭙﺲ ﺑﻮﺳﻴﻠﻪ ﻋﻤﻠﮕﺮ‬.1‫ﻣﺜﺎﻝ‬
.(‫ ﭼﻴﺪﻣﺎﻥ ﻋﻨﺎﺻﺮ ﺑﺮﻋﮑﺲ ﻣﻲ ﺷﻮﺩ )ﻳﻌﻨﻲ ﺑﻪ ﺻﻮﺭﺕ ﻧﺰﻭﻟﻲ‬Reverse
List<Customer> customers = new List<Customer>()
{
new Customer() {Name ="Ali",Family="Aghdam",Country="iran",CustomerID =0 },
new Customer() {Name ="Ali",Family="Nasiri",Country="england",CustomerID =1 },
new Customer() {Name ="Arash",Family="Novin",Country="india",CustomerID =2 },
new Customer() {Name ="Ali",Family="Novin",Country= "iran" , CustomerID =3 }
};

var query = from c in customers


orderby c.Family
select c;

foreach (var item in query)


{
Console.WriteLine(item);
}
‫|ﺻﻔﺤﻪ‪40‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﺠﻤﻌﻲ – ‪Agreagate Operators‬‬


‫ﺍﻳﻦ ﻋﻨﺎﺻﺮ ﺑﺮﺍﻱ ﻣﺤﺎﺳﺒﺎﺕ ﺑﺮ ﺭﻭﻱ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ ﻋﻨﻮﺍﻥ ﻣﺜﺎﻝ ﺟﻤﻊ ﺗﻤﺎﻡ ﻋﻨﺎﺻﺮ ﺩﺭ ﻳﮏ‬
‫ﻣﺠﻤﻮﻋﻪ ﻭ ﻳﺎ ﻣﻴﺎﻧﮕﻴﻦ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ‪.‬‬

‫ﻋﻤﻠﮕﺮ ‪Count‬‬
‫ﺍﺯ ﻋﻤﻠﮕﺮ ‪ Count‬ﻣﻲ ﺗﻮﺍﻥ ﺑﺮﺍﻱ ﻣﺤﺎﺳﺒﻪ ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‪.‬‬

‫(>‪public static int Count<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫(>‪public static int Count<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫ﻓﺮﻡ ﺍﻭﻝ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺯﻣﺎﻧﻲ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ ﮐﻪ ‪ source‬ﺭﺍﺑﻂ >‪ IEnumerable<TSource‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ‬
‫ﮐﺮﺩﻩ ﺑﺎﺷﺪ‪ ،‬ﺩﺭ ﺍﻳﻦ ﺻﻮﺭﺕ ﺍﺯ ﻣﺘﺪ )(‪ Count‬ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺷﺪﻩ ﺩﺭ ﺩﺭﻭﻥ ﺍﻳﻦ ﻭﺍﺳﻂ ﺑﺮﺍﻱ ﻣﺤﺎﺳﺒﻪ ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ‬
‫‪predicate‬‬ ‫ﺷﻮﺩ ﻭﻟﻲ ﺯﻣﺎﻧﻲ ﮐﻪ ‪ source‬ﺭﺍﺑﻂ >‪ IEnumerable<TSource‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻧﮑﺮﺩﻩ ﺑﺎﺷﺪ ﺑﻮﺳﻴﻠﻪ ﺗﺎﺑﻊ ﭘﺎﺭﺍﻣﺘﺮ‬
‫ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺷﻤﺎﺭﺵ ﻣﻲ ﮐﻨﺪ ﻭ ﺳﭙﺲ ﺑﺎ ﺍﻓﺰﻭﺩﻥ ‪ 1‬ﺑﻪ ﺑﻪ ﺁﻥ ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;)(‪int query = customers.Count‬‬

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


‫ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﮐﻪ ﻧﻮﻉ ﺧﺮﻭﺟﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﺯ ﻧﻮﻉ ‪ int‬ﻣﻲ ﺑﺎﺷﺪ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻣﺤﺪﻭﺩﻩ‬
‫‪ int‬ﺗﺠﺎﻭﺯ ﮐﻨﺪ‪ ،‬ﺍﺳﺘﺜﻨﺎﻱ ‪ OverflowException‬ﺭﺥ ﺧﻮﺍﻫﺪ ﺩﺍﺩ‪ ،‬ﺩﺭ ﺍﻳﻦ ﺻﻮﺭﺕ ﻣﻲ ﺗﻮﺍﻧﻴﺪ ﺍﺯ ﻋﻤﻠﮕﺮ ‪ LongCount‬ﺍﺳﺘﻔﺎﺩﻩ‬
‫ﮐﻨﻴﺪ‬

‫ﺑﺮﺍﻱ ﺑﻪ ﺩﺳﺖ ﺁﻭﺭﺩﻥ ﻣﺤﺪﻭﺩﻩ ‪ Int‬ﻣﻲ ﺗﻮﺍﻧﻴﺪ ﺍﺯ ﻣﺘﺪ ﻫﺎﻱ ‪ int.MaxValue‬ﻭ ‪ int.MinValue‬ﺍﺳﺘﻔﺎﺩﻩ ﮐﻨﻴﺪ‪.‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 41‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻋﻤﻠﮕﺮ ‪LongCount‬‬
‫ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮ ‪ Count‬ﺑﺮﺍﻱ ﻣﺤﺎﺳﺒﻪ ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ ﻭ ﺗﻨﻬﺎ ﺗﻔﺎﻭﺕ ﺁﻧﻬﺎ ﺍﻳﻦ‬
‫ﺧﺮﻭﺟﻲ ﺭﺍ ﺍﺯ ﻧﻮﻉ ‪ Long‬ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﮐﻪ ﺑﻮﺳﻴﻠﻪ ﺁﻥ ﻣﻲ ﺗﻮﺍﻥ ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﺑﻴﺸﺘﺮ ﺭﺍ ﻣﻮﺭﺩ‬ ‫ﺍﺳﺖ ﮐﻪ ﻋﻤﻠﮕﺮ‪LongCount‬‬

‫ﺷﻤﺎﺭﺵ ﻗﺮﺍﺭ ﺩﺍﺩ‪.‬‬

‫(>‪public static long LongCount<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫(>‪public static long LongCount<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫ﻓﺮﻡ ﺍﻭﻝ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺯﻣﺎﻧﻲ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ ﮐﻪ ‪ source‬ﺭﺍﺑﻂ >‪ IEnumerable<TSource‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ‬
‫ﮐﺮﺩﻩ ﺑﺎﺷﺪ‪ ،‬ﺩﺭ ﺍﻳﻦ ﺻﻮﺭﺕ ﺍﺯ ﻣﺘﺪ )(‪ Count‬ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺷﺪﻩ ﺩﺭ ﺩﺭﻭﻥ ﺍﻳﻦ ﻭﺍﺳﻂ ﺑﺮﺍﻱ ﻣﺤﺎﺳﺒﻪ ﺗﻌﺪﺍﺩ ﻋﻨﺎﺻﺮ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ‬
‫‪predicate‬‬ ‫ﺷﻮﺩ ﻭﻟﻲ ﺯﻣﺎﻧﻲ ﮐﻪ ‪ source‬ﺭﺍﺑﻂ >‪ IEnumerable<TSource‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻧﮑﺮﺩﻩ ﺑﺎﺷﺪ ﺑﻮﺳﻴﻠﻪ ﺗﺎﺑﻊ ﭘﺎﺭﺍﻣﺘﺮ‬
‫ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺷﻤﺎﺭﺵ ﻣﻲ ﮐﻨﺪ ﻭ ﺳﭙﺲ ﺑﺎ ﺍﻓﺰﻭﺩﻥ ‪ 1‬ﺑﻪ ﺗﻌﺪﺍﺩ ﺁﻥ ﻋﻨﺎﺻﺮ ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;)(‪long query = customers.LongCount‬‬

‫ﻋﻤﻠﮕﺮ ‪Sum‬‬
‫ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺍﻱ ﻣﺠﻤﻮﻉ ﻋﻨﺎﺻﺮ ﻋﺪﺩﻱ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ ﻭ ﺩﺍﺭﺍﻱ ﺩﻭ ﺳﺮﺑﺎﺭﮔﺰﺍﺭﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ‬
‫ﺍﺳﺖ‪.‬‬

‫;)‪public static Numeric Sum(this IEnumerable<Numeric> source‬‬

‫‪public static Numeric Sum<TSource>(this IEnumerable<TSource> source,‬‬


‫;)‪Func<TSource, Numeric> selector‬‬

‫ﺩﺭ ﺩﻭ ﻓﺮﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﻧﻮﻉ ﺑﺮﮔﺸﺘﻲ ‪ Numeric‬ﺩﻗﺖ ﮐﻨﻴﺪ‪ .‬ﺍﻳﻦ ﻧﻮﻉ ﻣﻲ ﺗﻮﺍﻧﺪ ﻳﮑﻴﺎﺯ ﺍﻧﻮﺍﻉ ﺯﻳﺮ ﺑﺎﺷﺪ‪.‬‬

‫>‪Int , Nullable<int> , long , Nullable<long> , double , Nullable<double> , decimal , Nullable<decimal‬‬


42‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

‫ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻉ ﺗﻤﺎﻣﻲ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮﺩ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺑﺮﮔﺸﺖ ﺩﺍﺩﻩ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﺍﻳﻦ‬
.‫ ﺗﻌﻴﻴﻦ ﺷﺪﻩ ﺑﺎﺷﺪ‬selector ‫ﻣﺠﻤﻮﻉ ﻋﻨﺎﺻﺮﻱ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﻣﺤﺎﺳﺒﻪ ﻣﻲ ﺷﻮﺩ ﮐﻪ ﺗﻮﺳﻂ ﺗﺎﺑﻊ‬

.‫ﻣﺜﺎﻝ‬

int[] integers = { 5, 3, 8, 9, 1, 7 };
int sum = integers.Sum();
Console.WriteLine("Total of all Numbers : {0}", sum.ToString());

Max ‫ ﻭ‬Min ‫ﻋﻤﻠﮕﺮ‬


.‫ ﺑﻪ ﺗﺮﺗﻴﺐ ﮐﻮﭼﮑﺘﺮﻳﻦ ﻭ ﺑﺰﺭﮔﺘﺮﻳﻦ ﻋﻨﺼﺮ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﻨﺪ‬Max ‫ ﻭ‬Min ‫ﻋﻤﻠﮕﺮﻫﺎﻱ‬

public static Numeric Min/Max(


this IEnumerable<Numeric> source);

public static TSource Min<TSource>/Max<TSource>(


this IEnumerable<TSource> source);

public static Numeric Min<TSource>/Max<TSource>(


this IEnumerable<TSource> source,
Func<TSource, Numeric> selector);

public static TResult Min<TSource, TResult>/Max<TSource, TResult>(


this IEnumerable<TSource> source,
Func<TSource, TResult> selector);

‫ ﺗﺎﺑﻊ‬،‫ ﺭﺍ ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﻨﺪ ﻭ ﺳﭙﺲ ﺑﺮﺍﻱ ﭘﻴﺪﺍ ﮐﺮﺩﻥ ﺑﺰﺭﮔﺘﺮﻳﻦ ﻭ ﻳﺎ ﮐﻮﭼﮑﺘﺮﻳﻦ ﻣﻘﺪﺍﺭ‬source ‫ﺍﻳﻦ ﺩﻭ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻪ‬
‫ ﮐﻮﭼﮑﺘﺮﻳﻦ ﻭ ﻳﺎ ﺑﺰﺭﮔﺘﺮﻳﻦ ﻋﻨﺼﺮ ﺑﺮ‬،‫ ﺗﻌﻴﻴﻦ ﻧﺸﺪﻩ ﺑﺎﺷﺪ‬selector ‫ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﭘﺎﺭﺍﻣﺘﺮ‬،‫ ﺭﺍ ﻓﺮﺍﺧﻮﺍﻧﻲ ﻣﻲ ﮐﻨﻨﺪ‬selector
.‫ﺍﺳﺎﺱ ﻣﻘﺪﺍﺭﺷﺎﻥ ﺍﻧﺘﺨﺎﺏ ﻭ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﻧﺪ‬

.‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﺍﻳﻦ ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﭘﻴﺪﺍ ﮐﺮﺩﻥ ﮐﻮﭼﮑﺘﺮﻳﻦ ﻭ ﺑﺰﺭﮔﺘﺮﻳﻦ ﺍﻋﺪﺍﺩ ﺩﺭ ﺑﻴﻦ ﻣﺠﻤﻮﻋﻪ ﺍﻋﺪﺍﺩ ﻣﺜﺎﻝ ﻗﺒﻠﻲ‬.1‫ﻣﺜﺎﻝ‬

int[] integers = { 5, 3, 8, 9, 1, 7 };
int max = integers.Max();
int min = integers.Min();
Console.WriteLine("Min ={0} and Max = {1}", max , min);
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬43 ‫ﺻﻔﺤﻪ‬

.1 ‫ ﻣﺸﺘﺮﻱ ﺑﺎ ﮐﺪ‬،‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺍﻱ ﭘﻴﺪﺍ ﮐﺮﺩﻥ ﺑﻴﺸﺘﺮﻳﻦ ﺳﻔﺎﺭﺵ‬.2‫ﻣﺜﺎﻝ‬

List<Customer> customers = new List<Customer>()


{
new Customer() {
Name ="Ali",
Family = "Aghdam" ,
Country = "iran" ,
CustomerID =0 },
};

List<Order> orders = new List<Order>()


{
new Order() { CustomerID = 0 , Total = 1000},
new Order() { CustomerID = 0 , Total = 1200},
new Order() { CustomerID = 0 , Total = 200},
new Order() { CustomerID = 0 , Total = 500}
};

var query = from c in customers


join o in orders
on c.CustomerID equals o.CustomerID
select new { c.CustomerID, c.Family, o.Total };

foreach (var item in query)


{
Console.WriteLine(item);
}

// Max Order
Console.WriteLine( query.Max(c => c.Total) );

//Min Order
Console.WriteLine( query.Min(c => c.Total) );
44‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

Average ‫ﻋﻤﻠﮕﺮ‬
.‫ﺑﺎ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻲ ﺗﻮﺍﻥ ﻣﻴﺎﻧﮕﻴﻦ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮﺩ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﻣﺤﺎﺳﺒﻪ ﻧﻤﻮﺩ‬

public static Result Average(


this IEnumerable<Numeric> source);

public static Result Average<TSource>(


this IEnumerable<TSource> source,
Func<TSource, Numeric> selector);

‫ ﻣﺤﺎﺳﺒﻪ ﻣﻲ ﺷﻮﺩ ﻭ ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﻣﻴﺎﻧﮕﻴﻦ‬source ‫ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻴﺎﻧﮕﻴﻦ ﻋﻨﺎﺻﺮ ﻣﻮﺟﻮﺩ ﺩﺭ ﻣﺠﻤﻮﻋﻪ‬
‫ ﻧﻮﻉ ﺧﺮﻭﺟﻲ ﺩﺭ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺎ ﻋﻤﻠﮕﺮ ﻫﺎﻱ ﻗﺒﻠﻲ ﺗﻔﺎﻭﺕ ﺩﺍﺭﺩ ﻭ ﺑﻪ‬.‫ ﻣﺤﺎﺳﺒﻪ ﻣﻲ ﺷﻮﻧﺪ‬selector ‫ﻋﻨﺎﺻﺮ ﺑﺮ ﺍﺳﺎﺱ ﺗﺎﺑﻊ‬
Double ‫ ﺧﺮﻭﺟﻲ ﺍﺯ ﻧﻮﻉ‬Int64 ‫ ﻭ‬Int32 ‫ﺑﻮﺩﻥ ﻧﻮﻉ ﻫﺎﻱ ﻋﺪﺩﻱ ﺑﺴﺘﮕﻲ ﺩﺍﺭﺩ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻧﻮﻉ ﻫﺎﻱ ﻋﺪﺩﻱ‬nullability
Nullable<Double> ‫ ﺑﺎﺷﺪ ﺧﺮﻭﺟﻲ ﺍﺯ ﻧﻮﻉ‬Nullable<Int64> ‫ ﻭ‬Nullable<Int32> ‫ﺧﻮﺍﻫﺪ ﺑﻮﺩ ﻭ ﺍﮔﺮ ﻧﻮﻉ ﻫﺎﻱ ﻋﺪﺩﻱ‬
.‫ﺧﻮﺍﻫﺪ ﺑﻮﺩ‬

‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ‬.1‫ﻣﺜﺎﻝ‬

int[] integers = { 5, 3, 8, 9, 1, 7 };

double average = integers.Average();

Console.WriteLine("Average = {0}", average);

‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ‬.2‫ﻣﺜﺎﻝ‬

List<Customer> customers = new List<Customer>()


{
new Customer() {Name ="Ali" , Family = "Aghdam" , Country = "iran" ,
CustomerID =0 },
};

List<Order> orders = new List<Order>()


{
new Order() { CustomerID = 0 , Total = 1000},
new Order() { CustomerID = 0 , Total = 1200},
new Order() { CustomerID = 0 , Total = 200},
new Order() { CustomerID = 0 , Total = 500}
};

var query = from c in customers


join o in orders
on c.CustomerID equals o.CustomerID
select new { c.CustomerID, c.Family, o.Total };

Console.WriteLine( query.Average(c => c.Total) );


www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬45 ‫ﺻﻔﺤﻪ‬

Aggregate ‫ﻋﻤﻠﮕﺮ‬
.‫ﺍﻳﻦ ﺗﺎﺑﻊ ﺍﻳﻦ ﺍﻣﺎﮐﻦ ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﻳﮏ ﺗﺎﺑﻊ ﺭﺍ ﺑﺮ ﺭﻭﻱ ﻫﺮﻳﮏ ﺍﺯ ﺍﻋﻀﺎﺀ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺟﺮﺍ ﻧﻤﺎﻳﻴﻢ‬

public static T Aggregate<TSource>(


this IEnumerable<TSource> source,
Func<TSource, TSource, TSource> func);

public static TAccumulate Aggregate<TSource, TAccumulate>(


this IEnumerable<TSource> source,
TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> func);

public static TResult Aggregate<TSource, TAccumulate, TResult>(


this IEnumerable< TSource > source,
TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> func,
Func<TAccumulate, TResult> resultSelector);

‫ ﺩﺭ ﻓﺮﻡ‬.‫)ﻳﻌﻨﻲ ﻧﻘﻄﻪ ﺷﺮﻭﻉ(ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﺩ‬ Aggregate ‫ ﺑﻪ ﻋﻨﻮﺍﻥ ﺍﻭﻟﻴﻦ ﻣﻘﺪﺍﺭ ﻋﻤﻠﮕﺮ‬source ‫ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﺩﺭ‬

‫ ﺍﺯ ﻧﻮﻉ‬seed ‫ ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﺩ ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﭘﺎﺭﺍﻣﺘﺮ‬source ‫ﺍﻭﻝ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻧﻘﻄﻪ ﺷﺮﻭﻉ ﺍﺯ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ‬
‫ ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﺩ ﻭ ﺩﺭ ﻓﺮﻡ ﺳﻮﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺗﺎﺑﻊ‬Aggregate ‫ ﺑﻪ ﻋﻨﻮﺍﻥ ﻧﻘﻄﻪ ﺷﺮﻭﻉ ﺑﺮﺍﻱ ﺗﺎﺑﻊ‬TAccumulate
.‫ ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺘﻪ ﻣﻲ ﺷﻮﺩ‬aggregate ‫ ﺑﻪ ﻋﻨﻮﺍﻥ ﻧﻮﻋﻲ ﺷﺮﻁ ﺑﺮﺍﻱ ﭘﺎﻳﺎﻥ ﮐﺎﺭ‬resultSelector

Aggregate ‫ ﺑﻪ ﻭﺳﻴﻠﻪ ﻋﻤﻠﮕﺮ‬Sum ‫ ﺷﺒﻴﻪ ﺳﺎﺯﻱ‬.1‫ﻣﺜﺎﻝ‬

List<int> SampleList = new List<int>() { 1, 1, 2, 3, 5, 8, 13 };

int AggCount = SampleList.Aggregate((counter, listItem) =>


counter += listItem);

Console.WriteLine(string.Format("Aggregate count is: {0}", AggCount));

Aggregate ‫ ﺑﺮﺍﻱ ﺭﺷﺘﻪ ﺑﻮﺳﻠﻪ ﻋﻤﻠﮕﺮ‬Reverse ‫ ﺷﺒﻴﻪ ﺳﺎﺯﻱ ﻧﻮﻋﻲ‬.2‫ﻣﺜﺎﻝ‬

string sentence = "the quick brown fox jumps over the lazy dog";
// Split the string into individual words.

string[] words = sentence.Split(' ');


// Join each word to the beginning of the new sentence to reverse the word oder.

string reversed = words.Aggregate((workingSentence, next) =>


next + " " + workingSentence);

Console.WriteLine(reversed);
‫|ﺻﻔﺤﻪ‪46‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫*‪/‬‬
‫‪This code produces the following output:‬‬

‫‪dog lazy the over jumps fox brown quick the‬‬


‫‪*/‬‬

‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﻗﺴﻤﺖ ﺑﻨﺪﻱ – ‪Partitioning Operators‬‬


‫ﺍﻳﻦ ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﺗﻘﺴﻴﻢ ﺑﻨﺪﻱ ﻣﺠﻤﻮﻋﻪ ﻫﺎ ﺑﺪﻭﻥ ﻣﺮﺗﺐ ﺳﺎﺯﻱ‪ ،‬ﺑﻪ ﺩﻭ ﻳﺎ ﭼﻨﺪ ﻗﺴﻤﺖ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﻧﺪ‪.‬‬
‫ﻫﻤﭽﻨﻴﻦ ﺍﻳﻦ ﻋﻤﻠﮕﺮﻫﺎ ﻳﮏ ﻗﺴﻤﺖ ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﻨﺪ ﻭ ﺍﺯ ﺑﺎﻗﻲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺻﺮﻑ ﻧﻈﺮ ﻣﻲ ﮐﻨﻨﺪ‪ .‬ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ‬
‫ﮐﻪ ﺑﺮﺍﻱ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻣﮑﺎﻧﻴﺰﻡ ﺻﻔﺤﻪ ﺑﻨﺪﻱ ﺍﺳﺘﻔﺎﺩﻩ ﺯﻳﺎﺩﻱ ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮﻫﺎ ﺧﻮﺍﻫﻴﺪ ﻧﻤﻮﺩ‪.‬‬

‫ﻋﻤﻠﮕﺮ ‪Take‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺗﻌﺪﺍﺩﻱ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﺍﺳﺎﺱ ﻣﻘﺪﺍﺭ ﺍﺭﺳﺎﻟﻲ ﺑﻪ ﺁﻥ‪ ،‬ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪ .‬ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ‬
‫ﺯﻳﺮ ﺍﺳﺖ‪.‬‬

‫(>‪public static IEnumerable<TSource> Take<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Int32 count‬‬

‫ﺩﺭﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺑﻪ ﺗﻌﺪﺍﺩ ‪ count‬ﺗﺎ ﺍﺯ ﻋﻨﺎﺻﺮ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﺧﻮﺍﻫﻨﺪ ﺷﺪ‪.‬‬

‫ﻣﺜﺎﻝ‪ 5 .1‬ﻣﻘﺪﺍﺭ ﺍﻭﻝ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ‪SampleList‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 1, 2, 3, 5, 8, 13‬‬

‫;)‪var query = SampleList.Take(5‬‬

‫)‪foreach (var item in query‬‬


‫{‬
‫‪Console.Write(item + ",‬‬ ‫;)"‬
‫}‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 47‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻋﻤﻠﮕﺮ ‪Skip‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺗﻌﺪﺍﺩﻱ ﻣﺸﺨﺺ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺻﺮﻑ ﻧﻈﺮ ﮐﺮﺩﻩ ﻭ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﺑﺎﻗﻴﻤﺎﻧﺪﻩ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ‬
‫ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫(>‪public static IEnumerable<TSource> Skip<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Int32 count‬‬

‫ﺩﺭﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺍﺑﺘﺪﺍ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺑﻪ ﺗﻌﺪﺍﺩ ‪ count‬ﺗﺎ ﺷﻤﺎﺭﺵ ﺷﺪﻩ ﻭ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﺑﺎﻗﻴﻤﺎﻧﺪﻩ ﺩﺭ ﻣﺠﻤﻮﻋﻪ‬
‫‪ source‬ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﺧﻮﺍﻫﻨﺪ ﺷﺪ‪.‬‬

‫ﻣﺜﺎﻝ‪ .1‬ﺻﺮﻑ ﻧﻈﺮ ﮐﺮﺩﻥ ﺍﺯ ‪ 5‬ﻋﻨﺼﺮ ﺍﻭﻝ ﺩﺭ ﻟﻴﺴﺖ ‪ SampleList‬ﻭ ﺍﻧﺘﺨﺎﺏ ﻋﻨﺎﺻﺮ ﺑﺎﻗﻴﻤﺎﻧﺪﻩ‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 1, 2, 3, 5, 8, 13‬‬

‫;)‪var query = SampleList.Skip(5‬‬

‫)‪foreach (var item in query‬‬


‫{‬
‫‪Console.Write(item + ",‬‬ ‫;)"‬
‫}‬

‫ﻋﻤﻠﮕﺮ ‪TakeWhile‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺗﺎ ﺯﻣﺎﻥ ﺑﺮﻗﺮﺍﺭ ﺑﻮﺩﻥ ﻳﮏ ﺷﺮﻁ ﻣﻌﻴﻦ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫(>‪public static IEnumerable<TSource> TakeWhile<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫(>‪public static IEnumerable<TSource> TakeWhile<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Int32, Boolean> predicate‬‬

‫ﺩﺭ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺗﺎ ﺯﻣﺎﻧﻲ ﮐﻪ ﺷﺮﻁ ﻣﺮﺑﻮﻁ ﺑﻪ ﭘﺎﺭﺍﻣﺘﺮ ‪ predicate‬ﻧﻘﺾ ﮔﺮﺩﺩ‪ ،‬ﺷﻤﺎﺭﺵ ﺷﺪﻩ ﻭ ﺩﺭ ﻳﮏ‬
‫ﻧﻤﻮﻧﻪ ﺍﺯ ﻧﻮﻉ >‪ IEnumerable<TSource‬ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ‪ .‬ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﺗﺎﺑﻊ ‪ predicate‬ﻳﮏ ﭘﺎﺭﺍﻣﺘﺮ ﺍﺯ ﻧﻮﻉ ‪ int‬ﺭﺍ ﺩﺍﺭﺍ ﻣﻲ‬
‫ﺑﺎﺷﺪ ﮐﻪ ﻣﺤﻞ ﻗﺮﺍﺭ ﮔﻴﺮﻱ ﻋﻨﺎﺻﺮ ﺑﺮ ﺭﻭﻱ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﻧﺸﺎﻥ ﻣﻲ ﺩﻫﺪ‪.‬‬
48‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

TakeWhile ‫ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﻋﻤﻠﮕﺮ‬.1‫ﻣﺜﺎﻝ‬

List<int> SampleList = new List<int>() { 1, 1, 2, 3, 5, 8, 13 };

var query = SampleList.TakeWhile(s => s <= 5 );

foreach (var item in query)


{
Console.Write(item + ", ");
}

TakeWhile ‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮ ﺩﻭﻡ ﻋﻤﻠﮕﺮ‬.2‫ﻣﺜﺎﻝ‬

List<int> SampleList = new List<int>() { 1, 1, 2, 3, 5, 8, 13 };

var query = SampleList.TakeWhile( (s,index) => (s > index) );

foreach (var item in query)


{
Console.Write(item + ", ");
}

SkipWhile ‫ﻋﻤﻠﮕﺮ‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﺯ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺗﺎ ﺯﻣﺎﻥ ﻧﻘﺾ ﻳﮏ ﺷﺮﻁ ﻣﻌﻴﻦ ﺻﺮﻑ ﻧﻈﺮ ﻣﻲ ﮐﻨﺪ ﻭ ﺑﺎﻗﻴﻤﺎﻧﺪﻩ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ‬
.‫ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﮐﻨﺪ‬

public static IEnumerable<TSource> SkipWhile<TSource>(


this IEnumerable<TSource> source,
Func<TSource, Boolean> predicate);

public static IEnumerable<TSource> SkipWhile<TSource>(


this IEnumerable<TSource> source,
Func<TSource, Int32, Boolean> predicate);

‫ ﺻﺮﻑ ﻧﻈﺮ ﻣﻲ‬،‫ ﻧﻘﺾ ﮔﺮﺩﺩ‬predicate ‫ ﺗﺎ ﺯﻣﺎﻧﻲ ﮐﻪ ﺷﺮﻁ ﻣﺮﺑﻮﻁ ﺑﻪ ﭘﺎﺭﺍﻣﺘﺮ‬source ‫ﺩﺭ ﺍﻳﻦ ﻋﻤﻠﮕﺮﺍﺯ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
‫ ﺩﺭ‬.‫ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﮔﺮﺩﻧﺪ‬IEnumerable<TSource> ‫ﺷﻮﺩ ﻭ ﺑﺎﻗﻴﻤﺎﻧﺪﻩ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺩﺭ ﻗﺎﻟﺐ ﻳﮏ ﻧﻤﻮﻧﻪ ﺍﺯ ﻧﻮﻉ‬
‫ ﺭﺍ ﺩﺍﺭﺍ ﻣﻲ ﺑﺎﺷﺪ ﮐﻪ ﻣﺤﻞ ﻗﺮﺍﺭ ﮔﻴﺮﻱ ﻋﻨﺎﺻﺮ ﺑﺮ ﺭﻭﻱ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﻧﺸﺎﻥ‬int ‫ ﻳﮏ ﭘﺎﺭﺍﻣﺘﺮ ﺍﺯ ﻧﻮﻉ‬predicate ‫ﻓﺮﻡ ﺩﻭﻡ ﺗﺎﺑﻊ‬
.‫ﻣﻲ ﺩﻫﺪ‬
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬49 ‫ﺻﻔﺤﻪ‬

SkipWhile ‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﻋﻤﻠﮕﺮ‬.1‫ﻣﺜﺎﻝ‬

List<int> SampleList = new List<int>() { 1, 1, 2, 3, 5, 8, 13 };

var query = SampleList.SkipWhile( s => s < 5 );

foreach (var item in query)


{
Console.Write(item + ", ");
}

SkipWhile ‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﻋﻤﻠﮕﺮ‬.2‫ﻣﺜﺎﻝ‬

List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13 };

var query = SampleList.SkipWhile((s, index) => (s > index));

foreach (var item in query)


{
Console.Write(item + ", ");
}
50‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

Concatation Operator - ‫ﻋﻤﻠﮕﺮ ﺍﻟﺤﺎﻗﻲ‬


‫ ﮔﻔﺘﻪ ﻣﻲ ﺷﻮﺩ ﻭ ﺗﻨﻬﺎ ﻋﻤﻠﮕﺮ ﺍﻳﻦ‬Concatenation ‫ﺩﻭ ﻋﻤﻞ ﻣﻠﺤﻖ ﻧﻤﻮﺩﻥ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺑﻪ ﻳﮑﺪﻳﮕﺮ ﺍﻟﺤﺎﻕ ﺳﺎﺯﻱ ﻭ ﻳﺎ‬
.‫ ﺍﺳﺖ‬Concat ‫ ﻋﻤﻠﮕﺮ‬،‫ﺧﺎﻧﻮﺍﺩﻩ‬

Concat ‫ﻋﻤﻠﮕﺮ‬
.‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ ﻫﻢ ﻣﺘﺼﻞ ﻣﻲ ﮐﻨﺪ‬

public static IEnumerable<TSource> Concat<TSource>(


this IEnumerable<TSource> first,
IEnumerable<TSource> second);

‫ ﺍﺳﺖ ﻭ ﺗﻨﻬﺎ ﺷﺮﻁ ﺩﺭ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻳﮑﺴﺎﻥ ﺑﻮﺩﻥ ﺩﻭ‬IEnumerable<TSource> ‫ﺧﺮﻭﺟﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﺯ ﻧﻮﻉ‬
.‫ ﺍﺯ ﻳﮏ ﻧﻮﻉ ﺍﺳﺖ‬second ‫ ﻭ‬first ‫ﭘﺎﺭﺍﻣﺘﺮ‬

.‫ ﺑﻪ ﻳﮑﺪﻳﮕﺮ‬SampleList2 ‫ ﻭ‬SampleList1 ‫ ﻣﺘﺼﻞ ﮐﺮﺩﻥ ﺩﻭ ﻣﺠﻤﻮﻋﻪ‬.1‫ﻣﺜﺎﻝ‬

List<int> SampleList1 = new List<int>() { 1, 3, 2, 3, 5, 8, 13 };


List<int> SampleList2 = new List<int>() { 16, 20, 25 };

var query = SampleList1.Concat(SampleList2);

foreach (var item in query)


Console.Write(item + ", ");

Element Operators - ‫ﻋﻤﻠﮕﺮ ﻫﺎﻱ ﻋﻨﺼﺮﻱ‬


.‫ﺍﻳﻦ ﺩﺳﺘﻪ ﺍﺯ ﻋﻤﻠﮕﺮ ﻫﺎ ﻳﮏ ﻋﻨﺼﺮ ﺧﺎﺹ ﻭ ﻳﺎ ﻳﮏ ﻋﻨﺼﺮ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﻨﺪ‬

First ‫ﻋﻤﻠﮕﺮ‬
.‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬.‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‬

public static TSource First<TSource>(


this IEnumerable<TSource> source);

public static TSource First<TSource>(


this IEnumerable<TSource> source,
Func<TSource, Boolean> predicate);
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 51‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﻣﺠﻤﻮﻋﻪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ‪ ،‬ﻋﻨﺎﺻﺮ‬
‫ﺍﺳﺖ‪ ،‬ﺑﺮﺭﺳﻲ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮﻱ ﮐﻪ ﺻﺤﺖ ﺷﺮﻁ ﺭﺍ‬ ‫‪predicate‬‬ ‫ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﺍﺑﺘﺪﺍ ﺑﻮﺳﻴﻠﻪ ﺷﺮﻁ ﮐﻪ ﻫﻤﺎﻥ ﺗﺎﺑﻊ‬
‫ﺑﺮﻗﺮﺍﺭ ﮐﻨﺪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪.‬‬

‫ﻣﺜﺎﻝ‪ .1‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‪.‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;)(‪var query = SampleList.First‬‬

‫;)‪Console.Write(query‬‬

‫ﻣﺜﺎﻝ‪ .2‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‪.‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;) ‪var query = SampleList.First( c => c>1‬‬

‫;)‪Console.Write(query‬‬

‫ﻋﻤﻠﮕﺮ ‪FirstOrDefault‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻋﻨﺼﺮﻱ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﻭﺟﻮﺩ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﺪ ﻭ ﻳﺎ ﺷﺮﻁ‬
‫ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﻧﮑﻨﺪ‪ ،‬ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺿﻲ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪ .‬ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪.‬‬

‫(>‪public static TSource FirstOrDefault<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫(>‪public static TSource FirstOrDefault<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﻣﺠﻤﻮﻋﻪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﻋﻨﺎﺻﺮ‬
‫ﺍﺳﺖ‪ ،‬ﺑﺮﺭﺳﻲ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮﻱ ﮐﻪ ﺻﺤﺖ ﺷﺮﻁ ﺭﺍ‬ ‫‪predicate‬‬ ‫ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﺍﺑﺘﺪﺍ ﺑﻮﺳﻴﻠﻪ ﺷﺮﻁ ﮐﻪ ﻫﻤﺎﻥ ﺗﺎﺑﻊ‬
‫ﺑﺮﻗﺮﺍﺭ ﮐﻨﺪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺩﺭ ﻫﺮ ﻳﮏ ﺍﺯ ﺩﻭ ﻓﺮﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺼﺮﻱ‬
‫ﻣﻮﺟﻮﺩ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺿﻲ ﺍﺯ ﺁﻥ ﻧﻮﻉ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪.‬‬
52‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

. FirstOrDefault ‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﻋﻤﻠﮕﺮ‬.1‫ﻣﺜﺎﻝ‬

List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13 };

var query = SampleList.FirstOrDefault();

Console.Write(query);

. FirstOrDefault ‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﻋﻤﻠﮕﺮ‬.2‫ﻣﺜﺎﻝ‬

List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13 };

var query = SampleList.FirstOrDefault( c => c > 3 );

Console.Write(query);

Last ‫ﻋﻤﻠﮕﺮ‬
.‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬.‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‬

public static TSource Last<TSource>(


this IEnumerable<TSource> source);

public static TSource Last<TSource>(


this IEnumerable<TSource> source,
Func<TSource, Boolean> predicate);

‫ ﻋﻨﺎﺻﺮ‬،‫ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻣﺠﻤﻮﻋﻪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ‬
(‫ ﺑﺮﺭﺳﻲ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮﻱ )ﺍﺯ ﺍﻧﺘﻬﺎﻱ ﻣﺠﻤﻮﻋﻪ‬،‫ﺍﺳﺖ‬ predicate ‫ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﺍﻧﺘﻬﺎ ﺑﻮﺳﻴﻠﻪ ﺷﺮﻁ ﮐﻪ ﻫﻤﺎﻥ ﺗﺎﺑﻊ‬
.‫ﮐﻪ ﺻﺤﺖ ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﺪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‬

.‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‬.1‫ﻣﺜﺎﻝ‬

List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13 };

var query = SampleList.Last();

Console.Write(query);
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 53‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻣﺜﺎﻝ‪ .2‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‪.‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;) ‪var query = SampleList.Last ( c => c>1‬‬

‫;)‪Console.Write(query‬‬

‫ﻋﻤﻠﮕﺮ ‪LastOrDefault‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻋﻨﺼﺮﻱ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﻭﺟﻮﺩ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﺪ ﻭ ﻳﺎ‬
‫ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﻧﮑﻨﺪ‪ ،‬ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺿﻲ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪ .‬ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪.‬‬

‫(>‪public static TSource LastOrDefault<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫(>‪public static TSource LastOrDefault<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﻣﺠﻤﻮﻋﻪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﻋﻨﺎﺻﺮ‬
‫ﺍﺳﺖ‪ ،‬ﺑﺮﺭﺳﻲ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﺍﻭﻟﻴﻦ ﻋﻨﺼﺮﻱ )ﺍﺯ ﺍﻧﺘﻬﺎ( ﮐﻪ ﺻﺤﺖ‬ ‫‪predicate‬‬ ‫ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﺍﻧﺘﻬﺎ ﺑﻮﺳﻴﻠﻪ ﺷﺮﻁ ﮐﻪ ﻫﻤﺎﻥ ﺗﺎﺑﻊ‬
‫ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﺪ ﺑﻪ ﻋﻨﻮﺍﻥ ﺁﺧﺮﻳﻦ ﻋﻨﺼﺮ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪ .‬ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺩﺭ ﻫﺮ ﻳﮏ ﺍﺯ ﺩﻭ ﻓﺮﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‬
‫ﻋﻨﺼﺮﻱ ﻣﻮﺟﻮﺩ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﻣﻘﺪﺍﺭ ﭘﻴﺶ ﻓﺮﺿﻲ ﺍﺯ ﺁﻥ ﻧﻮﻉ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪.‬‬

‫ﻣﺜﺎﻝ‪ .1‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﻋﻤﻠﮕﺮ ‪. FirstOrDefault‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;)(‪var query = SampleList.LastOrDefault‬‬

‫;)‪Console.Write(query‬‬
‫|ﺻﻔﺤﻪ‪54‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﻣﺜﺎﻝ‪ .2‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﻋﻤﻠﮕﺮ ‪. FirstOrDefault‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;) ‪var query = SampleList.LastOrDefault( c => c > 3‬‬

‫;)‪Console.Write(query‬‬

‫ﻋﻤﻠﮕﺮ ‪Single‬‬
‫ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺍﻱ ﺍﻧﺘﺨﺎﺏ ﻳﮏ ﻋﻨﺼﺮ ﺧﺎﺹ ﻭ ﻳﮑﺘﺎ ﺍﺯ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‪.‬ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ‬
‫ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪.‬‬

‫(>‪public static TSource Single<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫(>‪public static TSource Single<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫ﻓﺮﻡ ﺍﻭﻝ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺯﻣﺎﻧﻲ ﮐﻪ ﺗﻨﻬﺎ ﻳﮏ ﻋﻤﻠﮕﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﻣﻮﺟﻮﺩ ﺑﺎﺷﺪ‪ ،‬ﺁﻥ ﻋﻤﻠﮕﺮ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ‬
‫‪ source‬ﺗﻬﻲ ﻭ ﻳﺎ ﺑﻴﺸﺘﺮ ﺍﺯ ﻳﮏ ﻋﻨﺼﺮ ﺩﺍﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﺍﺳﺘﺜﻨﺎ‬ ‫ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻣﺠﻤﻮﻋﻪ‬
‫‪ InvalidOperationException‬ﺭﺥ ﻣﻲ ﺩﻫﺪ‪.‬‬

‫ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﺍﺳﺘﻔﺎﺩﻩ ﺷﻮﺩ ﻳﻌﻨﻲ ﺍﻳﻨﮑﻪ ﻳﮏ ﺷﺮﻁ ﺑﺎ ﭘﺎﺭﺍﻣﺘﺮ ‪ predicate‬ﺍﺭﺳﺎﻝ ﺷﻮﺩ ﻭ ﺩﺭ ﺑﻴﻦ ﻋﻨﺎﺻﺮ‬
‫ﻣﺠﻤﻮﻋﻪ ﺗﻨﻬﺎ ﻳﮏ ﻋﻨﺼﺮ ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﺪ‪ ،‬ﺁﻥ ﻋﻨﺼﺮ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭﺻﻮﺭﺗﻲ ﮐﻪ ﻫﻴﭻ ﻋﻨﺼﺮﻱ‬
‫ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﻧﮑﻨﺪ ﻭ ﻳﺎ ﭼﻨﺪﻳﻦ ﻋﻨﺼﺮ ﺷﺮﻁ ‪predicate‬ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﻨﺪ‪ ،‬ﺍﺳﺘﺜﻨﺎﺀ ‪ InvalidOperationException‬ﺭﺥ ﻣﻲ‬
‫ﺩﻫﺪ‪.‬‬

‫ﻣﺜﺎﻝ‪ .1‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﻋﻤﻠﮕﺮ ‪Single‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;)(‪var query = SampleList.Single‬‬


‫‪//throw a InvalidOperationException Exception‬‬

‫;)‪Console.Write(query‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 55‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻣﺜﺎﻝ‪ .2‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﻋﻤﻠﮕﺮ‪Single‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;)‪var query = SampleList.Single( c => c == 3‬‬


‫‪//throw a InvalidOperationException Exception‬‬

‫;)‪Console.Write(query‬‬

‫ﻋﻤﻠﮕﺮ ‪SingleOrDefault‬‬
‫ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺍﻱ ﺍﻧﺘﺨﺎﺏ ﻳﮏ ﻋﻨﺼﺮ ﺧﺎﺹ ﻭ ﻳﮑﺘﺎ ﺍﺯ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‪.‬ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ‬
‫ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪.‬‬

‫(>‪public static TSource SingleOrDefault<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫(>‪public static TSource SingleOrDefault<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫ﻓﺮﻡ ﺍﻭﻝ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺯﻣﺎﻧﻲ ﮐﻪ ﺗﻨﻬﺎ ﻳﮏ ﻋﻤﻠﮕﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﻣﻮﺟﻮﺩ ﺑﺎﺷﺪ‪ ،‬ﺁﻥ ﻋﻤﻠﮕﺮ ﺑﻪ ﻋﻨﻮﺍﻥ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ‬
‫ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺗﻬﻲ ﻭ ﻳﺎ ﺑﻴﺸﺘﺮ ﺍﺯ ﻳﮏ ﻋﻨﺼﺮ ﺩﺍﺷﺘﻪ ﺑﺎﺷﺪ‪ ،‬ﻳﮏ ﻧﻤﻮﻧﻪ ﭘﻴﺶ ﻓﺮﺽ ﺍﺯ ﻧﻮﻉ‬
‫‪ source‬ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﮔﺮﺩﺩ‪.‬‬

‫ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﺍﺳﺘﻔﺎﺩﻩ ﺷﻮﺩ ﻳﻌﻨﻲ ﺍﻳﻨﮑﻪ ﻳﮏ ﺷﺮﻁ ﺑﺎ ﭘﺎﺭﺍﻣﺘﺮ ‪ predicate‬ﺍﺭﺳﺎﻝ ﺷﻮﺩ ﻭ ﺩﺭ ﺑﻴﻦ ﻋﻨﺎﺻﺮ‬
‫ﻣﺠﻤﻮﻋﻪ ﺗﻨﻬﺎ ﻳﮏ ﻋﻨﺼﺮ ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﺪ‪ ،‬ﺁﻥ ﻋﻨﺼﺮ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﺩﺭﺻﻮﺭﺗﻲ ﮐﻪ ﻫﻴﭻ ﻋﻨﺼﺮﻱ‬
‫ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﻧﮑﻨﺪ ﻭ ﻳﺎ ﭼﻨﺪﻳﻦ ﻋﻨﺼﺮ ﺷﺮﻁ ‪predicate‬ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﻨﺪ‪ ،‬ﻳﮏ ﻧﻤﻮﻧﻪ ﭘﻴﺶ ﻓﺮﺽ ﺍﺯ ﻧﻮﻉ ‪ source‬ﺑﻪ ﺧﺮﻭﺟﻲ‬
‫ﺍﺭﺳﺎﻝ ﻣﻲ ﮔﺮﺩﺩ‪.‬‬

‫‪predicate‬ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﻨﺪ‪ ،‬ﺍﺳﺘﺜﻨﺎﺀ‬ ‫ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﮐﻪ ﺩﺭ ﻫﺮ ﺩﻭ ﻓﺮﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‪ ،‬ﺍﮔﺮ ﭼﻨﺪﻳﻦ ﻋﻨﺼﺮ ﺷﺮﻁ‬
‫‪InvalidOperationException‬ﺭﺥ ﻣﻲ ﺩﻫﺪ‪.‬‬
‫|ﺻﻔﺤﻪ‪56‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﻣﺜﺎﻝ‪ .1‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺍﻭﻝ ﻋﻤﻠﮕﺮ ‪. SingleOrDefault‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;)(‪var query = SampleList.SingleOrDefault‬‬


‫‪//throw a InvalidOperationException Exception‬‬

‫;)‪Console.Write(query‬‬

‫ﻣﺜﺎﻝ‪ .2‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﻋﻤﻠﮕﺮ‪. SingleOrDefaul‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;)‪var query = SampleList. SingleOrDefault ( c => c == 4‬‬


‫‪//throw a InvalidOperationException Exception‬‬

‫;)‪Console.Write(query‬‬

‫ﻋﻤﻠﮕﺮ ‪ElementAt‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺼﺮﻱ ﺭﺍ ﮐﻪ ﺍﻧﺪﻳﺲ ﺁﻥ ﺑﻪ ﻋﻨﻮﺍﻥ ﭘﺎﺭﺍﻣﺘﺮ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪ ،‬ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪) .‬ﺍﻧﺪﻳﺲ ﺍﺯ ﺻﻔﺮ ﺷﺮﻭﻉ ﻣﻲ ﺷﻮﺩ(‬
‫ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪.‬‬

‫(>‪public static TSource ElementAt<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Int32 index‬‬

‫ﺩﺭ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻮﺳﻴﻠﻪ ﺷﻤﺎﺭﺵ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ‪ ، source‬ﻋﻨﺼﺮﻱ ﮐﻪ ﺩﺍﺭﺍﻱ ﺍﻧﺪﻳﺲ ‪ index‬ﺍﺳﺖ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ‬
‫ﻣﻲ ﺷﻮﺩ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺍﻧﺪﻳﺲ ﻭﺍﺭﺩ ﺷﺪﻩ ﻣﻌﺘﺒﺮ ﻧﺒﺎﺷﺪ ﻳﮏ ﺍﺳﺘﺜﻨﺎ ﺍﺯ ﻧﻮﻉ ‪ ArgumentNullException‬ﺭﺥ ﻣﻲ ﺩﻫﺪ‪ .‬ﻧﮑﺘﻪ‬
‫ﻗﺎﺑﻞ ﺗﻮﺟﻪ ﺩﺭ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﻳﻦ ﺍﺳﺖ ﮐﻪ ﺍﮔﺮ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺭﺍﺑﻂ >‪ IList<T‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩﻩ ﻳﺎﺷﺪ ﻋﻨﺎﺻﺮ ﺑﻪ ﺻﻮﺭﺕ‬
‫ﻣﺴﺘﻘﻴﻢ ﺷﻤﺎﺭﺵ ﻧﻤﻲ ﺷﻮﻧﺪ ﺑﻠﮑﻪ ﺑﻮﺳﻴﻠﻪ ﺗﻮﺍﺑﻊ ﺩﺍﺧﻠﻲ ﺍﻱ ﺭﺍﺑﻂ ﻋﻨﺼﺮ ﺩﺍﺭﺍﻱ ﺍﻧﺪﻳﺲ ‪ index‬ﺑﺮﮔﺪﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ‪.‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 57‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;)‪var query = SampleList.ElementAt(4‬‬

‫;)‪Console.Write(query‬‬

‫ﻋﻤﻠﮕﺮ ‪ElementAtOrDefault‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺼﺮﻱ ﺭﺍ ﮐﻪ ﺍﻧﺪﻳﺲ ﺁﻥ ﺑﻪ ﻋﻨﻮﺍﻥ ﭘﺎﺭﺍﻣﺘﺮ ﺍﺭﺳﺎﻝ ﻣﻲ ﺷﻮﺩ‪ ،‬ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪) .‬ﺍﻧﺪﻳﺲ ﺍﺯ ﺻﻔﺮ ﺷﺮﻭﻉ ﻣﻲ ﺷﻮﺩ(‬
‫ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪.‬‬

‫(>‪public static TSource ElementAt<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Int32 index‬‬

‫ﺩﺭ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻮﺳﻴﻠﻪ ﺷﻤﺎﺭﺵ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ‪ ، source‬ﻋﻨﺼﺮﻱ ﮐﻪ ﺩﺍﺭﺍﻱ ﺍﻧﺪﻳﺲ ‪ index‬ﺍﺳﺖ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ‬
‫ﻣﻲ ﺷﻮﺩ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﺍﻧﺪﻳﺲ ﻣﻮﺭﺩ ﻧﻈﺮ ﻣﻌﺘﺒﺮ ﻧﺒﺎﺷﺪ‪ ،‬ﻳﮏ ﻧﻤﻮﻧﻪ ﭘﻴﺶ ﻓﺮﺽ ﺍﺯ ﻧﻮﻉ ‪ source‬ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ‬
‫ﺷﻮﺩ‪ .‬ﻧﮑﺘﻪ ﻗﺎﺑﻞ ﺗﻮﺟﻪ ﺩﺭ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﻳﻦ ﺍﺳﺖ ﮐﻪ ﺍﮔﺮ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺭﺍﺑﻂ >‪ IList<T‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩﻩ ﻳﺎﺷﺪ ﻋﻨﺎﺻﺮ‬
‫ﺑﻪ ﺻﻮﺭﺕ ﻣﺴﺘﻘﻴﻢ ﺷﻤﺎﺭﺵ ﻧﻤﻲ ﺷﻮﻧﺪ ﺑﻠﮑﻪ ﺑﻮﺳﻴﻠﻪ ﺗﻮﺍﺑﻊ ﺩﺍﺧﻠﻲ ﺍﻱ ﺭﺍﺑﻂ ﻋﻨﺼﺮ ﺩﺍﺭﺍﻱ ﺍﻧﺪﻳﺲ ‪ index‬ﺑﺮﮔﺪﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 5, 8, 13‬‬

‫;)‪var query = SampleList.ElementAt(4‬‬

‫;)‪Console.Write(query‬‬
58‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

DefaultEmpty ‫ﻋﻤﻠﮕﺮ‬
‫ ﻓﺮﮎ ﮐﻠﻲ ﺍﻳﻦ‬.‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺍﻱ ﺟﺎﻳﮕﺰﻳﻦ ﮐﺮﺩﻥ ﻳﮏ ﻋﻨﺼﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺑﺎ ﻋﻨﺼﺮ ﭘﻴﺶ ﻓﺮﺽ ﺗﻌﻮﻳﺾ ﻣﻲ ﮐﻨﺪ‬
:‫ﻋﻤﻠﮕﺮ ﺑﻪ ﺩﻭ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static IEnumerable<TSource> DefaultIfEmpty<TSource>(


this IEnumerable<TSource> source);

public static IEnumerable<TSource> DefaultIfEmpty<TSource>(


this IEnumerable<TSource> source,
TSource defaultValue);

‫ ﺗﻬﻲ ﺑﺎﺷﺪ ﻳﮏ‬source ‫ﺭﺍ ﺑﺮﻣﻲ ﺭﮔﺮﺩﺍﻧﺪ ﻭﻟﻲ ﻣﺠﻤﻮﻋﻪ‬ source ‫ﺁﺭﺍﻳﻪ ﺍﺯ ﻧﻮﻉ‬ ‫ﺑﻪ ﺻﻮﺭﺕ ﭘﻴﺶ ﻓﺮﺽ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻳﮏ‬
‫ ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﮐﻪ ﺍﮔﺮ ﺍﺯ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﺳﺘﻔﺎﺩﻩ ﺷﻮﺩ ﻳﻌﻨﻲ ﻧﻮﻋﻲ‬.‫ ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‬source ‫ﻧﻤﻮﻧﻪ ﭘﻴﺶ ﻓﺮﺽ ﺍﺯ ﻧﻮﻉ‬
.‫ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‬null ‫ ﺍﺯ‬،‫ﺑﺮﺍﻱ ﭘﻴﺶ ﻓﺮﺽ ﻣﻌﻴﻦ ﻧﺸﺪﻩ ﺑﺎﺷﺪ‬

. DefaultEmpty ‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺣﺎﻟﺖ ﺍﻭﻝ ﻋﻤﻠﮕﺮ‬.1‫ﻣﺜﺎﻝ‬

var expr = customers.DefaultIfEmpty(); // Null

. DefaultEmpty ‫ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺣﺎﻟﺖ ﺩﻭﻡ ﻋﻤﻠﮕﺮ‬.1‫ﻣﺜﺎﻝ‬

List<Customer> customers = new List<Customer>()


{
new Customer() {Name ="Ali",Family = "Aghdam",Country = "iran" , CustomerID =0 },
new Customer() {Name ="Majid",Family="Shah Mohammadi",Country="iran",CustomerID =1 }
};
var query = from c in customers
select new { c.CustomerID, c.Family } ;

foreach (var item in query.DefaultIfEmpty() )


{
Console.WriteLine("Family : " + item.Family);
}

Customer defaultCustomer = new Customer() {


Family = "Default Name" , CustomerID=2 };
List<Customer> emptyCustomer = new List<Customer>();

foreach (var item in emptyCustomer.DefaultIfEmpty(defaultCustomer) )


{
Console.WriteLine("Family : " + item.Family);
}
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 59‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﻮﻟﻴﺪﻱ – ‪Generation Operators‬‬


‫ﺍﻳﻦ ﺩﺳﺘﻪ ﺍﺯ ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﺗﻮﻟﻴﺪ ﻣﺠﻤﻮﻋﻪ ﺍﻱ ﺍﺯ ﻋﻨﺎﺻﺮ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ‪ .‬ﺩﺭ ﺍﺩﺍﻣﻪ ﺍﻳﻦ ﺗﻮﻉ ﻋﻤﻠﮕﺮﻫﺎ ﺭﺍ‬
‫ﺑﺮﺭﺳﻲ ﺧﻮﺍﻫﻴﻢ ﮐﺮﺩ‪.‬‬

‫ﻋﻤﻠﮕﺮ ‪Repeat‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﮐﻪ ﺣﺎﺻﻞ ﺗﮑﺮﺍﺭ ﻳﮏ ﻋﻨﺼﺮ ﺑﻪ ﺗﻌﺪﺍﺩ ﻣﻌﻴﻨﻲ ﺍﺳﺖ‪ ،‬ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ ﻭ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ‬
‫ﻣﻲ ﮐﻨﺪ‪ .‬ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪:‬‬

‫(>‪public static IEnumerable<TResult> Repeat<TResult‬‬


‫‪TResult element,‬‬
‫;)‪int count‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍ ﺍﺯ ﻧﻮﻉ ﻋﻤﻠﮕﺮ ‪ element‬ﺑﻪ ﺗﻌﺪﺍﺩ ‪ count‬ﺗﮑﺮﺍﺭ ﻧﻤﻮﺩﻩ ﻭ ﻣﺠﻤﻮﻋﻪ ﺣﺎﺻﻞ ﮐﻪ ﺍﺯ ﻧﻮﻉ‬
‫>‪ IEnumerable<TResult‬ﺍﺳﺖ‪ ،‬ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫‪Customer majidShahm = new Customer() { Name = "Majid", Family = "Shah‬‬


‫;} ‪Mohammadi", Country = "iran", CustomerID = 1‬‬

‫;)‪IEnumerable<Customer> customers = Enumerable.Repeat(majidShahm, 4‬‬

‫)‪foreach (var item in customers‬‬


‫{‬
‫;)‪Console.WriteLine("Family : " + item.Family‬‬
‫}‬

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


‫‪Ϯ‬‬
‫ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﺩﺭ ﻫﻨﮕﺎﻡ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‪ ،‬ﻧﻮﻉ ﻣﻮﺭﺩ ﻧﻈﺮ ﺍﺯ ﺍﻧﻮﺍﻉ ﺍﺭﺟﺎﻋﻲ ﺑﺎﺷﺪ‪ ،‬ﮐﭙﻲ ﻫﺎﻱ ﮐﻪ ﺍﺯ ﻧﻮﻉ ﻣﻮﺭﺩ‬
‫‪newC‬‬ ‫ﻧﻈﺮ ﺍﻳﺠﺎﺩ ﻣﻲ ﺷﻮﻧﺪ ﺑﻪ ﻫﻤﺎﻥ ﻧﻮﻉ ﻗﺒﻞ ﺍﺷﺎﺭﻩ ﻣﻴﮑﻨﻨﺪ‪ ،‬ﻳﻌﻨﻲ ﺍﮔﺮ ﺑﺮﻧﺎﻣﻪ ﺍﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﻢ ﺑﺎ ﺗﻐﻴﻴﺮ‬
‫ﺧﺼﻮﺻﻴﺎﺕ ﻫﻤﻪ ﻱ ﮐﭙﻲ ﻫﺎ ﺍﺯ ﺷﻲ ﺗﻐﻴﻴﺮ ﺧﻮﺍﻫﻨﺪ ﮐﺮﺩ ﮐﻪ ﺍﻣﺮﻱ ﮐﺎﻣﻼ ﻣﻨﻄﻘﻲ ﺍﺳﺖ‪.‬‬

‫‪Customer majidShahm = new Customer() { Name = "Majid", Family = "Shah‬‬


‫;} ‪Mohammadi", Country = "iran", CustomerID = 1‬‬

‫;)‪IEnumerable<Customer> customers = Enumerable.Repeat(majidShahm, 4‬‬

‫‪2‬‬
‫‪Reference type‬‬
60‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

foreach (var item in customers)


{
Console.WriteLine("Family : " + item.Family);
}

Customer newC = customers.First();

newC.Family = "Aghdam";

foreach (var item in customers)


{
Console.WriteLine("Family : " + item.Family);
}

//Out:
//Family : Shah Mohammadi
//Family : Shah Mohammadi
//Family : Shah Mohammadi
//Family : Shah Mohammadi
//Family : Aghdam
//Family : Aghdam
//Family : Aghdam
//Family : Aghdam

Range ‫ﻋﻤﻠﮕﺮ‬
‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ‬.‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻪ ﺍﻱ ﻣﺸﺨﺺ ﺍﺯ ﺍﻋﺪﺍﺩ ﭘﺸﺖ ﺳﺮ ﻫﻢ ﺭﺍ ﺩﺭ ﻃﻴﻒ ﻣﺸﺨﺼﻲ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ‬
:‫ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static IEnumerable<Int32> Range(


Int32 start,
Int32 count);

.‫ ﺗﻮﻟﻴﺪ ﻣﻲ ﮐﻨﺪ‬count ‫ ﺑﻪ ﺗﻌﺪﺍﺩ‬start ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻪ ﺍﻱ ﺍﺯ ﺍﻋﺪﺍﺩ ﺭﺍ ﺍﺯ ﻣﻘﺪﺍﺭ‬

.1‫ﻣﺜﺎﻝ‬

var query = Enumerable.Range(1, 5);

foreach (var item in query)


Console.WriteLine(item);
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬61 ‫ﺻﻔﺤﻪ‬

. Aggregate ‫ ﻭ‬Range ‫ ﺷﺒﻴﻪ ﺳﺎﺯﻱ ﺗﺎﺑﻊ ﻓﺎﮐﺘﻮﺭﻳﻞ ﺑﻮﺳﻴﻠﻪ ﻋﻤﻠﮕﺮ‬.2‫ﻣﺜﺎﻝ‬

static int Factorial(int number)


{
return (Enumerable.Range(0, number + 1)
.Aggregate(0, (s, t) => t == 0 ? 1 : s *= t));
}

Empty ‫ﻋﻤﻠﮕﺮ‬
:‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬.‫ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺗﻬﻲ ﺍﺯ ﻳﮏ ﻧﻮﻉ ﻣﺸﺨﺺ ﺭﺍ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ‬Empty ‫ﻋﻤﻠﮕﺮ‬

public static IEnumerable<TResult> Empty<TResult>();

.‫ ﺍﻳﺠﺎﺩ ﮐﺮﺩﻩ ﻭ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﮐﻨﺪ‬IEnumerable<TResult> ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻪ ﺍﻱ ﺗﻬﻲ ﺍﺯ ﻧﻮﻉ‬

.‫ﻣﺜﺎﻝ‬

IEnumerable<Order> emptyOrder = Enumerable.Empty<Order>();


‫|ﺻﻔﺤﻪ‪62‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﻨﻄﻴﻢ ﮐﻨﻨﺪﻩ – ‪Set Operators‬‬


‫ﺍﻳﻦ ﺩﺳﺘﻪ ﺍﺯ ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﺍﻧﺠﺎﻡ ﺍﻋﻤﺎﻟﻲ ﻧﻈﻴﺮ ﺍﺟﺘﻤﺎﻉ ‪ ،‬ﺍﺷﺘﺮﺍﮎ ﻭ‪ ...‬ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ ﮐﻪ ﺩﺭ ﺍﻳﻦ ﺩﺳﺘﻪ ‪4‬‬
‫¡‪ Union‬ﻭ ‪ Except‬ﻗﺮﺍﺭ ﺩﺍﺭﺩ ﮐﻪ ﺩﺭ ﺍﺩﺍﻣﻪ ﺁﻧﻬﺎ ﺭﺍ ﺑﺮﺭﺳﻲ ﺧﻮﺍﻫﻴﻢ ﮐﺮﺩ‪.‬‬ ‫ﻋﻤﻠﮕﺮ ‪Intersect¡ Distinct‬‬

‫ﻋﻤﻠﮕﺮ ‪Distinct‬‬
‫ﻋﻤﻠﮕﺮ ‪ Distinct‬ﻋﻨﺎﺻﺮ ﺗﮑﺮﺍﺭﻱ ﻣﻮﺟﻮﺩ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺣﺬﻑ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﻣﻌﺪﻝ ﻣﺎﺩﻩ ‪ DISTICT‬ﺩﺭ ‪ SQL‬ﺍﺳﺖ ﮐﻪ‬
‫ﺩﺭ ‪ Join‬ﺍﺯ ﺁﻥ ﺍﺳﺘﻔﺎﺩﻩ ﺯﻳﺎﺩﻱ ﻣﻲ ﺷﻮﺩ‪ .‬ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺍﺭﺍﻱ ﺩﻭ ﺳﺮﺑﺎﺭﮔﺰﺍﺭﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪:‬‬

‫(>‪public static IEnumerable<TSource> Distinct<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫(>‪public static IEnumerable<TSource> Distinct<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪IEqualityComparer<TSource> comparer‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺍﻱ ﺍﻧﺠﺎﻡ ﻋﻤﻠﻴﺎﺕ ﺩﺭ ﺍﺑﺘﺪﺍ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ >‪ IEnumerable<TSource‬ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ ﺳﭙﺲ ﻋﻨﺎﺻﺮ‬
‫ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺭﺍ ﺷﻤﺎﺭﺵ ﮐﺮﺩﻩ ﻭ ﻋﻨﺎﺻﺮﻱ ﮐﻪ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﻭﺟﻮﺩ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﻨﺪ ﺑﻪ ﺁﻥ ﺍﺿﺎﻓﻪ ﻣﻲ ﮔﺮﺩﻧﺪ ﮐﻪ ﺩﺭ‬
‫ﺑﺮﺭﺳﻲ ﻋﻨﺎﺻﺮ ﺑﺮﺍﻱ ﺗﮑﺮﺍﺭﻱ ﻧﺒﻮﺩﻥ ﺍﺯ ﻣﺘﺪﻫﺎﻱ ‪ GetHashCode‬ﻭ ‪ Equal‬ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ ﮐﻪ ﻣﻲ ﺗﻮﺍﻥ ﺑﺮﺍﻱ ﺑﺮﺭﺳﻲ‬
‫‪IEqulityComparer‬‬ ‫ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻳﮏ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ ﺳﻔﺎﺭﺷﻲ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‪ .‬ﻣﻘﺎﻳﺴﻪ ﺳﻔﺎﺭﺷﻲ ﻣﻲ ﺑﺎﻳﺴﺖ ﺭﺍﺑﻂ‬
‫ﺭﺍﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﻧﻤﻮﺩﻩ ﺑﺎﺷﺪ‪.‬‬

‫ﻣﺜﺎﻝ‪.1‬‬

‫;} ‪List<int> SampleList = new List<int>() { 1, 3, 2, 3, 1, 8, 13‬‬

‫;)(‪var query = SampleList.Distinct‬‬

‫)‪foreach (var item in query‬‬


‫;)‪Console.WriteLine(item‬‬

‫ﻣﺜﺎﻝ‪ .2‬ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﻋﻤﻠﻴﺎﺕ ‪. Join‬‬

‫= ‪var expr‬‬
‫‪(from c in customers‬‬
‫‪from o in c.Orders‬‬
‫‪join p in products‬‬
‫‪on o.IdProduct equals p.IdProduct‬‬
‫‪select p‬‬
‫;)(‪).Distinct‬‬
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬63 ‫ﺻﻔﺤﻪ‬

Intersect ‫ﻋﻤﻠﮕﺮ‬
‫ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺍﺭﺍﻱ ﺩﻭ ﺳﺮﺑﺎﺭﮔﺰﺍﺭﻱ‬.‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺍﺯ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﻓﻘﻂ ﻋﻨﺎﺻﺮﻱ ﮐﻪ ﺩﺭ ﻫﺮ ﺩﻭ ﻣﻮﺟﻮﺩ ﺑﺎﺷﻨﺪ ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‬
:‫ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static IEnumerable<TSource> Intersect<TSource>(


this IEnumerable<TSource> first,
IEnumerable<TSource> second);

public static IEnumerable<TSource> Intersect<TSource>(


this IEnumerable<TSource> first,
IEnumerable<TSource> second,
IEqualityComparer<TSource> comparer);

first ‫ ﺭﺍ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ ﻭ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬IEnumerable<TSource> ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺍﺑﺘﺪﺍ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻧﻮﻉ‬
‫ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻋﻨﺼﺮﻱ ﺩﺭ ﻫﺮ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﻣﺸﺘﺮﮎ‬،‫ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﮐﻨﺪ‬second ‫ﺭﺍ ﺗﮏ ﺑﻪ ﺗﮏ ﺧﻮﺍﻧﺪﻩ ﻭ ﺑﺎ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
‫ ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺭﺳﻲ ﻣﺸﺘﺮﮎ ﺑﻮﺩﻥ ﻋﻨﺎﺻﺮ ﺑﻪ ﻭﺳﻴﻠﻪ ﻣﺘﺪﻫﺎﻱ‬.‫ﺑﺎﺷﺪ ﺑﻪ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﺍﺿﺎﻓﻪ ﻣﻲ ﮔﺮﺩﺩ‬
‫ ﺭﺍ‬IEqualityComparer ‫ ﺍﻧﺠﺎﻡ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ ﻳﮏ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ ﺳﻔﺎﺭﺷﻲ ﮐﻪ ﺭﺍﺑﻂ‬Equal ‫ ﻭ‬GetHashCode
.‫ ﺑﺮﺍﻱ ﻣﻘﺎﻳﺴﻪ ﻋﻨﺎﺻﺮ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‬،‫ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩﻩ ﺑﺎﺷﺪ‬

List<int> SampleList1 = new List<int>() { 1, 3, 2, 3, 1, 8, 13 };


List<int> SampleList2 = new List<int>() { 1, 5, 7, 3, 1, 6};

var query = SampleList1.Intersect(SampleList2);

foreach (var item in query)


Console.WriteLine(item);
‫|ﺻﻔﺤﻪ‪64‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﻋﻤﻠﮕﺮ ‪Union‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﺩﻭ ﻣﺠﻮﻋﻪ ﻣﺘﻔﺎﻭﺕ ﺭﺍ ﺑﻪ ﻳﮑﺪﻳﮕﺮ ﻣﺘﺼﻞ ﻣﻲ ﮐﻨﺪ ﻭ ﺩﺍﺭﺍﻱ ﺩﻭ ﺳﺮﺑﺎﺭﮔﺰﺍﺭﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪:‬‬

‫(>‪public static IEnumerable<TSource> Union<TSource‬‬


‫‪this IEnumerable<TSource> first,‬‬
‫;)‪IEnumerable<TSource> second‬‬

‫(>‪public static IEnumerable<TSource> Union<TSource‬‬


‫‪this IEnumerable<TSource> first,‬‬
‫‪IEnumerable<TSource> second,‬‬
‫;)‪IEqualityComparer<TSource> comparer‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻧﻴﺰ ﻫﻤﺎﻧﻨﺪ ﻋﻤﻠﮕﺮﻫﺎﻱ ‪ Distinct‬ﻭ ‪ Intersect‬ﺩﺭ ﺍﺑﺘﺪﺍ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻧﻮﻉ >‪ IEnumerable<TSource‬ﺭﺍ‬
‫ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ ﻭ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ‪ first‬ﺭﺍ ﺗﮏ ﺑﻪ ﺗﮏ ﺧﻮﺍﻧﺪﻩ ﻭ ﻋﻨﺎﺻﺮ ﻏﻴﺮ ﺗﮑﺮﺍﺭﻱ ﺭﺍ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﻗﺮﺍﺭ ﻣﻲ‬
‫ﺭﺍ ﺗﮏ ﺑﻪ ﺗﮏ ﺧﻮﺍﻧﺪﻩ ﻭ ﺑﺎ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﮐﻨﺪ‪ ،‬ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ‬ ‫‪second‬‬ ‫ﺩﻫﺪ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
‫ﮐﻪ ﻋﻨﺼﺮﻱ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﻭﺟﻮﺩ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﺪ ﺑﻪ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﺍﺿﺎﻓﻪ ﻣﻲ ﮔﺮﺩﺩ‪ .‬ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺭﺳﻲ‬
‫ﻣﺸﺘﺮﮎ ﺑﻮﺩﻥ ﻋﻨﺎﺻﺮ ﺑﻪ ﻭﺳﻴﻠﻪ ﻣﺘﺪﻫﺎﻱ ‪ GetHashCode‬ﻭ ‪ Equal‬ﺍﻧﺠﺎﻡ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ ﻳﮏ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ‬
‫ﺳﻔﺎﺭﺷﻲ ﮐﻪ ﺭﺍﺑﻂ ‪ IEqualityComparer‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩﻩ ﺑﺎﺷﺪ‪ ،‬ﺑﺮﺍﻱ ﻣﻘﺎﻳﺴﻪ ﻋﻨﺎﺻﺮ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;} ‪List<int> SampleList1 = new List<int>() { 1, 3, 2, 3, 1, 8, 13‬‬


‫;}‪List<int> SampleList2 = new List<int>() { 1, 5, 7, 3, 1, 6‬‬

‫;)‪var query = SampleList1.Union(SampleList2‬‬

‫)‪foreach (var item in query‬‬


‫;)‪Console.WriteLine(item‬‬
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 65‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻋﻤﻠﮕﺮ ‪Except‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻮﻋﻪ ﺭﺍ ﮐﻪ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺩﻳﮕﺮ ﻭﺟﻮﺩ ﻧﺪﺍﺷﺘﻪ ﺑﺎﺷﺪ ﺭﺍ ﺑﻪ ﺧﺮﻭﺟﻲ ﺍﺭﺳﺎﻝ ﻣﻲ ﮐﻨﺪ ﻭ ﺩﺍﺭﺍﻱ ﺩﻭ‬
‫ﺳﺮﺑﺎﺭﮔﺰﺍﺭﻱ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪:‬‬

‫(>‪public static IEnumerable<TSource> Except<TSource‬‬


‫‪this IEnumerable<TSource> first,‬‬
‫;)‪IEnumerable<TSource> second‬‬

‫(>‪public static IEnumerable<TSource> Except<TSource‬‬


‫‪this IEnumerable<TSource> first,‬‬
‫‪IEnumerable<TSource> second,‬‬
‫;)‪IEqualityComparer<TSource> comparer‬‬

‫‪first‬‬ ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺍﺑﺘﺪﺍ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻧﻮﻉ >‪ IEnumerable<TSource‬ﺭﺍ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ ﻭ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
‫ﺭﺍ ﺗﮏ‬ ‫‪second‬‬ ‫ﺭﺍ ﺗﮏ ﺑﻪ ﺗﮏ ﺧﻮﺍﻧﺪﻩ ﻭ ﻋﻨﺎﺻﺮ ﻏﻴﺮ ﺗﮑﺮﺍﺭﻱ ﺭﺍ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
‫ﺑﻪ ﺗﮏ ﺧﻮﺍﻧﺪﻩ ﻭ ﺑﺎ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﻣﻘﺎﻳﺴﻪ ﻣﻲ ﮐﻨﺪ‪ ،‬ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻋﻨﺼﺮﻱ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ‪ second‬ﺑﺎ ﻋﻨﺼﺮﻱ ﺩﺭ‬
‫ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﻣﺸﺘﺮﮎ ﺑﺎﺷﺪ‪ ،‬ﺁﻥ ﻋﻨﺼﺮ ﺍﺯ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪ ﺣﺬﻑ ﻣﻲ ﮔﺮﺩﺩ‪ .‬ﺩﺭ ﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺭﺳﻲ ﻣﺸﺘﺮﮎ‬
‫ﺑﻮﺩﻥ ﻋﻨﺎﺻﺮ ﺑﻪ ﻭﺳﻴﻠﻪ ﻣﺘﺪﻫﺎﻱ ‪ GetHashCode‬ﻭ ‪ Equal‬ﺍﻧﺠﺎﻡ ﻣﻲ ﺷﻮﺩ ﻭﻟﻲ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ ﻳﮏ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ ﺳﻔﺎﺭﺷﻲ‬
‫ﮐﻪ ﺭﺍﺑﻂ ‪ IEqualityComparer‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩﻩ ﺑﺎﺷﺪ‪ ،‬ﺑﺮﺍﻱ ﻣﻘﺎﻳﺴﻪ ﻋﻨﺎﺻﺮ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‪.‬‬

‫ﺗﻮﺟﻪ ﺩﺍﺷﺘﻪ ﺑﺎﺷﻴﺪ ﮐﻪ ﻣﺠﻤﻮﻋﻪ ﺧﺮﻭﺟﻲ ﺩﺭ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻪ ﺍﻱ ﺷﺎﻣﻞ ﺗﻤﺎﻡ ﻋﻨﺎﺻﺮ ﻏﻴﺮ ﻣﺸﺘﺮﮎ ﻣﺠﻤﻮﻋﻪ ‪ first‬ﺑﺎ‬
‫‪ second‬ﺍﺳﺖ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;} ‪List<int> SampleList1 = new List<int>() { 1, 3, 2, 3, 1, 8, 13‬‬


‫;}‪List<int> SampleList2 = new List<int>() { 1, 5, 7, 3, 1, 6‬‬

‫;)‪var query = SampleList1.Except(SampleList2‬‬

‫)‪foreach (var item in query‬‬


‫;)‪Console.WriteLine(item‬‬

‫‪//output‬‬
‫‪//2‬‬
‫‪//8‬‬
‫‪//13‬‬
66‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


‫ ﺑﻪ ﺍﻳﻦ ﻧﮑﺘﻪ ﺗﻮﺟﻪ ﮐﻨﻴﺪ ﮐﻪ ﻓﺮﻡ ﺍﻭﻝ ﺍﻳﻦ‬Except ‫ ﻭ‬Union ¡ Intersect ¡ Distinct ‫ﺩﺭ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﻟﺤﺎﻗﻲ‬
‫ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻋﻨﺎﺻﺮﻱ ﻭﺟﻮﺩ‬،‫ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﮐﻨﺪ‬Equal ‫ ﻭ‬GetHashCode ‫ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﻣﻘﺎﻳﺴﻪ ﻋﻨﺎﺻﺮ ﺍﺯ ﻣﺘﺪ ﻫﺎﻱ‬
‫ ﺗﻮﺳﻂ ﺍﻳﻦ ﻣﺘﺪ ﻫﺎ‬،‫ ﻫﺎﻱ ﻣﺘﻔﺎﻭﺗﻲ ﺑﺎﺷﻨﺪ ﻭﻟﻲ ﺍﺯ ﻧﻈﺮ ﻣﻨﺘﻄﻘﻲ ﺑﺎ ﻳﺪﻳﮕﺮ ﺑﺮﺍﺑﺮ ﺑﺎﺷﻨﺪ‬Reference ‫ﺩﺍﺷﺘﻪ ﺑﺎﺷﻨﺪ ﮐﻪ ﺩﺍﺭﺍﻱ‬
‫ ﺑﺮﺍﻱ ﮔﺮﻳﺰ ﺍﺯ ﺍﻳﻦ ﻣﺸﮑﻞ ﻣﻲ ﺗﻮﺍﻥ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ ﻭ ﻳﺎ‬.‫ﻋﻨﺎﺻﺮ ﻣﺘﻔﺎﻭﺕ ﻧﺘﻴﺠﻪ ﮔﻴﺮﻱ ﻣﻲ ﺷﻮﻧﺪ‬
.‫ﺍﻳﻨﮑﻪ ﺍﻳﺖ ﻣﺘﺪﻫﺎ ﺩﺭ ﺷﻲ ﻣﻮﺭﺩ ﻧﻈﺮ ﺭﺍ ﺑﺎﺯﻧﻮﻳﺴﻲ ﻧﻤﻮﺩ‬

‫ﺑﻪ ﻋﻨﻮﺍﻥ ﻣﺜﺎﻝ ﺩﺭ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺯﻳﺮ ﻳﮑﻲ ﺍﺯ ﻣﺸﺘﺮﻳﺎﻥ ﺍﺯ ﻧﻈﺮ ﻣﻌﻨﺎﻳﻲ ﺩﺭ ﻫﺮ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﻭﺟﻮﺩ ﺩﺍﺭﺩ ﻭﻟﻲ ﺑﻮﺳﻴﻠﻪ ﺍﻳﻦ‬
:‫ﺗﻮﺍﺑﻊ ﺑﻪ ﺍﺷﺘﺒﺎﻩ ﺍﻧﺘﺨﺎﺏ ﻣﻲ ﮔﺮﺩﺩ‬
Customer[] customerSetOne = {
new Customer {CustomerID = 46, Name = "Ali" , Family = "Aghdam"},
new Customer {CustomerID = 27, Name = "Vali" , Family = "piriZadeh" },
new Customer {CustomerID = 14, Name = "Majid" , Family = "Shah Mohammadi"}};

Customer[] customerSetTwo = {
new Customer {CustomerID = 23, Name = "Mohammad" , Family = "Ajhdari"},
new Customer {CustomerID = 22, Name = "Hossein" , Family = "Aghdam" },
new Customer {CustomerID = 46, Name = "Ali" , Family = "Aghdam"}};

var customerUnion = customerSetOne.Union(customerSetTwo);

foreach (var item in customerUnion)


{
Console.WriteLine(item);
}

//output
//Name = Ali , Family = Aghdam , CustomerID = 46
//Name = Vali , Family = piriZadeh , CustomerID = 27
//Name = Majid , Family = Shah Mohammadi , CustomerID = 14
//Name = Mohammad , Family = Ajhdari , CustomerID = 23
//Name = Hossein , Family = Aghdam , CustomerID = 22
//Name = Ali , Family = Aghdam , CustomerID = 46

‫ ﺩﺭ ﺯﻳﺮ‬.‫ ﺭﺍ ﺑﺎﺯﻧﻮﻳﺴﻲ ﻧﻤﻮﺩ‬GetHashCode ‫ﺑﺮﺍﻱ ﺍﺟﺘﻨﺎﺏ ﺍﺯ ﻣﺸﮑﻞ ﻣﻲ ﺗﻮﺍﻥ ﻳﺎ ﺍﺯ ﻓﺮﻡ ﺩﻭﻡ ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ ﻭ ﻳﺎ ﻣﺘﺪ ﻫﺎﻱ‬
:‫ﺍﻳﻦ ﺗﻮﺍﺑﻊ ﺭﺍ ﺑﺎﺯﻧﻮﻳﺴﻲ ﻧﻤﻮﺩﻩ ﺍﻳﻢ‬
public class Customer
{
public int CustomerID;
public string Name;
public string Family;

public override string ToString()


{
return String.Format("Name : {0} - Family: {1} , CustomerID : {2}",
this.Name, this.Family,this.CustomerID);
}
public override bool Equals(object obj)
{
if (!(obj is Customer))
return false;
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬67 ‫ﺻﻔﺤﻪ‬

else
{
Customer p = (Customer)obj;
return p.CustomerID == this.CustomerID ;
}
}
public override int GetHashCode()
{
return String.Format("{0}", this.CustomerID)
.GetHashCode();
}

:‫ﺣﺎﻻ ﺑﺎ ﺍﻧﺠﺎﻡ ﻣﺜﺎﻝ ﻗﺒﻠﻲ ﺧﺮﻭﺝ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺧﻮﺍﻫﺪ ﺑﻮﺩ‬


//output
//Name = Ali , Family = Aghdam , CustomerID = 46
//Name = Vali , Family = piriZadeh , CustomerID = 27
//Name = Majid , Family = Shah Mohammadi , CustomerID = 14
//Name = Mohammad , Family = Ajhdari , CustomerID = 23
//Name = Hossein , Family = Aghdam , CustomerID = 22

Zip ‫ﻋﻤﻠﮕﺮ‬
‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ‬.‫ ﺑﻪ ﺧﺎﻧﻮﺍﺩﻩ ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﻨﻈﻴﻢ ﮐﻨﻨﺪﻩ ﺍﺿﺎﻓﻪ ﺷﺪﻩ ﺍﺳﺖ‬.NET 4 ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ‬

:‫ﺍﺳﺖ‬

public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(


this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector);

‫ﺭﺍ ﺑﺎ ﻳﮑﺪﻳﮕﺮ ﺍﺩﻏﺎﻡ‬second ‫ ﺩﺭ ﻣﺠﻤﻮﻋﻪ‬،‫ ﺭﺍ ﺑﺎ ﻋﻨﺎﺻﺮ ﻣﺘﻨﺎﻇﺮ ﻣﺘﻨﺎﻇﺮ ﺑﻮﺳﻴﻠﻪ ﺍﻧﺪﻳﺲ‬first ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
‫ ﺑﻪ ﻃﻮﺭﻱ ﮐﻪ ﺩﻭ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ ﻳﮏ‬،‫ ﺑﻪ ﺧﺎﻃﺮ ﺷﺒﺎﻫﺖ ﺁﻥ ﺑﻪ ﺯﻳﭗ ﺑﻮﺩﻩ ﺍﺳﺖ‬Zip ‫ ﺩﻟﻴﻞ ﻧﺎﻡ ﮔﺰﺍﺭﻱ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ‬.‫ﻣﻲ ﮐﻨﺪ‬
.‫ ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‬، ‫ ﺑﺪﻭﻥ ﺗﻐﻴﻴﺮ ﻣﻮﻗﻌﻴﺖ‬،‫ﻣﺠﻤﻮﻋﻪ‬
68‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

.‫ﻣﺜﺎﻝ‬

Int32[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
DayOfWeek[] weekDays = {
DayOfWeek.Sunday,
DayOfWeek.Monday,
DayOfWeek.Tuesday,
DayOfWeek.Wednesday,
DayOfWeek.Thursday,
DayOfWeek.Friday,
DayOfWeek.Saturday};

var weekDaysNumbers = numbers.Zip(weekDays,


(first, second) => first + " - " +
second);

foreach (var item in weekDaysNumbers)


Console.WriteLine(item);

//output
//1 - Sunday
//2 - Monday
//3 - Tuesday
//4 - Wednseday
//5 - Thursday
//6 - Friday
//7 - Saturday

Quantifier Operators - ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﮐﻤﻴﺖ ﺳﻨﺞ‬


‫ ﺍﻳﻦ ﺩﺳﺘﻪ ﺷﺎﻣﻞ‬.‫ﺍﻳﻦ ﺩﺳﺘﻪ ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﭼﮏ ﮐﺮﺩﻥ ﻣﺠﻤﻮﻋﻪ ﻫﺎ ﺑﺮﺍﻱ ﺑﺮﻗﺮﺍﺭ ﺑﻮﺩﻥ ﺷﺮﻁ ﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﺷﻮﺩ‬
.‫ ﺍﺳﺖ ﮐﻪ ﺩﺭ ﺍﺩﺍﻣﻪ ﺁﻧﻬﺎ ﺭﺍ ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﻴﻢ‬Contains ‫ ﻭ‬Any ¡ All ‫ﻋﻤﻠﮕﺮ ﻫﺎﻱ‬

All ‫ﻋﻤﻠﮕﺮ‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺗﻤﺎﻣﻲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺎ ﻳﮏ ﺷﺮﻁ ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﺪ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﺗﻤﺎﻣﻲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺷﺮﻁ ﺭﺍ‬
:‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬.‫ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‬true ‫ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻘﺪﺍﺭ‬،‫ﺑﺮﻗﺮﺍﺭ ﮐﻨﻨﺪ‬

public static Boolean All<TSource>(


this IEnumerable<TSource> source,
Func<TSource, Boolean> predicate);
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 69‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍ ﮐﻠﻴﻪ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺭﺍ ﺑﺎ ﺷﺮﻁ ‪ predicate‬ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﺪ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﮐﻪ ﻫﻤﻪ‬
‫ﻱ ﻋﻨﺎﺻﺮ ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﻨﺪ‪ ،‬ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻘﺪﺍﺭ ‪ true‬ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ ﺩﺭ ﻏﻴﺮ ﺍﻳﻨﺼﻮﺭﺕ ﻣﻘﺪﺍﺭ ‪ false‬ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ‬
‫ﺷﻮﺩ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;} ‪List<int> SampleList1 = new List<int>() { 1, 3, 2, 3, 1, 8, 13‬‬

‫;))‪bool query = SampleList1.All( c => ((c % 2) == 0‬‬

‫;)‪Console.WriteLine(query‬‬

‫‪//output‬‬
‫‪//False‬‬

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


‫ﺍﮔﺮ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺗﻬﻲ ﺑﺎﺷﺪ‪ ،‬ﻋﻤﻠﮕﺮ ‪ All‬ﻫﻤﻴﺸﻪ ﻣﻘﺪﺍﺭ ‪ true‬ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪ ،‬ﺍﻳﻦ ﺑﻪ ﺧﺎﻃﺮ ﺍﻳﻦ ﺍﺳﺖ ﮐﻪ ﻣﺘﺪ‬
‫‪ predicate‬ﻫﻴﭻ ﻣﻮﻗﻊ ﻓﺮﺍﺧﻮﺍﻧﻲ ﻧﻤﻲ ﺷﻮﺩ ﻭ ﻋﻤﻠﮕﺮ ‪ All‬ﻣﻘﺪﺍﺭ ‪ true‬ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬

‫ﻋﻤﻠﮕﺮ ‪Any‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﺎ ﻳﮏ ﺷﺮﻁ ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﺪ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﻋﻨﺼﺮﻱ ﺷﺮﻁ ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﻨﺪ‪ ،‬ﺍﻳﻦ ﻋﻤﻠﮕﺮ‬
‫ﻣﻘﺪﺍﺭ ‪ true‬ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ‪ .‬ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪:‬‬

‫(>‪public static Boolean Any<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪Func<TSource, Boolean> predicate‬‬

‫(>‪public static Boolean Any<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺭﺍ ﺑﺎ ﺷﺮﻁ ‪ predicate‬ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﺪ ﻭ ﺩﺭ ﺻﻮﺭﺗﻲ ﻋﻨﺼﺮﻱ ﺷﺮﻁ‬
‫ﺭﺍ ﺑﺮﻗﺮﺍﺭ ﮐﻨﻨﺪ‪ ،‬ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﻘﺪﺍﺭ ‪ true‬ﺭﺍ ﺑﺮ ﻣﻲ ﮔﺮﺩﺍﻧﺪ ﻭ ﺩﺭ ﻏﻴﺮ ﺍﻳﻨﺼﻮﺭﺕ ﻣﻘﺪﺍﺭ ‪ false‬ﺑﺮﮔﺮﺩﺍﻧﺪﻩ ﻣﻲ ﺷﻮﺩ‪.‬‬
‫|ﺻﻔﺤﻪ‪70‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;} ‪List<int> SampleList1 = new List<int>() { 1, 3, 2, 3, 1, 8, 13‬‬

‫;))‪bool query = SampleList1.Any( c => ((c % 2) == 0‬‬

‫;)‪Console.WriteLine(query‬‬

‫‪//output‬‬
‫‪//True‬‬

‫ﻧﮑﺘﻪ ﺑﺴﻴﺎﺭ ﻣﻬﻢ‬


‫ﺍﮔﺮ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺗﻬﻲ ﺑﺎﺷﺪ‪ ،‬ﻋﻤﻠﮕﺮ ‪ Any‬ﻫﻤﻴﺸﻪ ﻣﻘﺪﺍﺭ ‪ true‬ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪ ،‬ﺍﻳﻦ ﺑﻪ ﺧﺎﻃﺮ ﺍﻳﻦ ﺍﺳﺖ ﮐﻪ ﻣﺘﺪ‬
‫‪ predicate‬ﻫﻴﭻ ﻣﻮﻗﻊ ﻓﺮﺍﺧﻮﺍﻧﻲ ﻧﻤﻲ ﺷﻮﺩ ﻭ ﻋﻤﻠﮕﺮ ‪ Any‬ﻣﻘﺪﺍﺭ ‪ true‬ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬

‫ﻋﻤﻠﮕﺮ ‪Contains‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺑﻪ ﺩﻧﺒﺎﻝ ﻳﮏ ﻋﻨﺼﺮ ﻣﺸﺨﺺ ﻣﻲ ﮔﺮﺩﺩ ﻭ ﺩﺭ ﺻﻮﺭﺕ ﻭﺟﻮﺩ‪ ،‬ﻣﻘﺪﺍﺭ ‪ true‬ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪.‬‬
‫ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪:‬‬

‫(>‪public static Boolean Contains<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫;)‪TSource value‬‬

‫(>‪public static Boolean Contains<TSource‬‬


‫‪this IEnumerable<TSource> source,‬‬
‫‪TSource value,‬‬
‫;)‪IEqualityComparer<TSource> comparer‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭﻫﻨﮕﺎﻡ ﺍﺟﺮﺍ ﺍﺑﺘﺪﺍ ﺑﺮﺭﺳﻲ ﻣﻲ ﮐﻨﺪ ﮐﻪ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺭﺍﺑﻂ >‪ ICollection<T‬ﺭﺍ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﺮﺩﻩ ﺑﺎﺷﺪ‬
‫ﺩﺭ ﺍﻳﻨﺼﻮﺭﺕ ﺍﺯ ﻣﺘﺪ ‪ Contain‬ﻣﺮﺑﻮﻁ ﺑﻪ ﺍﻳﻦ ﺭﺍﺑﻂ ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﮐﻨﺪ ﺩﺭ ﻏﻴﺮ ﺍﻳﻨﺼﻮﺭﺕ ﺗﻤﺎﻣﻲ ﺍﻋﻀﺎﺀ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺷﻤﺎﺭﺵ‬
‫ﻣﻲ ﮐﻨﺪ ﻭ ﺩﺭ ﺻﻮﺭﺕ ﻭﺟﻮﺩ ﻋﻨﺼﺮ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﻣﻘﺪﺍﺭ ‪ true‬ﺭﺍ ﺑﺮﻣﻲ ﮔﺮﺩﺍﻧﺪ‪ .‬ﺍﻟﺒﺘﻪ ﺑﺮﺍﻱ ﭼﮏ ﮐﺮﺩﻥ ﻋﻨﺎﺻﺮ ﺍﺯ‬
‫ﺗﻮﺍﺑﻊ ‪ GetHashCode‬ﻭ ‪ Equal‬ﺍﺳﺘﻔﺎﺩﻩ ﻣﻲ ﮐﻨﺪ )ﺑﺎ ﻭﺟﻮﺩ ﻫﻤﺎﻥ ﻣﺸﮑﻞ ﮐﻪ ﺩﺭ ﻗﺴﻤﺖ ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﻨﻈﻴﻢ ﮐﻨﻨﺪﻩ ﺗﻮﺿﻴﺢ‬
‫ﺩﺍﺩﻩ ﺷﺪ( ﻭﻟﻲ ﻣﻲ ﺗﻮﺍﻥ ﺗﻮﺳﻂ ﭘﺎﺭﺍﻣﺘﺮ ‪ compare‬ﻣﻲ ﺗﻮﺍﻥ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ ﺳﻔﺎﺭﺷﻲ ﺭﺍ ﺗﻨﻈﻴﻢ ﻧﻤﻮﺩ‪.‬‬
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬71 ‫ﺻﻔﺤﻪ‬

List<int> SampleList1 = new List<int>() { 1, 3, 2, 3, 1, 8, 13 };

bool query = SampleList1.Contains(2);

Console.WriteLine(query);

//output
//True

Conversion Operators – ‫ﻋﻤﻠﮕﺮﻫﺎﻱ ﺗﺒﺪﻳﻞ‬


‫ﺍﻳﻦ ﺩﺳﺘﻪ ﺍﺯ ﻋﻤﻠﮕﺮﻫﺎ ﺑﺮﺍﻱ ﺗﺒﺪﻳﻞ ﻣﺠﻤﻮﻋﻪ ﻭﺭﻭﺩﻱ ﺑﻪ ﺍﻧﻮﺍﻉ ﺩﻳﮕﺮ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ ﻭ ﺩﺭ ﺍﻳﻦ ﺩﺳﺘﻪ‬
‫ ﻭﺟﻮﺩ ﺩﺍﺭﻧﺪ‬Asquerable ‫ ﻭ‬AsEnumerable ¡ ToLookup ¡ ToList ¡ToDictionary ¡ ToArray ‫ ﻭ‬Cast ‫ﻋﻤﻠﮕﺮﻫﺎﻱ‬
.‫ﮐﻪ ﺩﺭ ﺍﺩﺍﻣﻪ ﺗﻮﺿﻴﺢ ﺧﻮﺍﻫﻴﻢ ﺩﺍﺩ‬

Cast ‫ﻋﻤﻠﮕﺮ‬
:‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬.‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ ﻳﮏ ﻧﻮﻉ ﻣﻌﻴﻦ ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‬

public static IEnumerable<TResult> Cast<TResult>(


this IEnumerable source);

‫ ﺗﺒﺪﻳﻞ ﮐﺮﺩﻩ ﻭ ﺩﺭ ﻳﮏ ﻧﻤﻮﻧﻪ‬TResult ‫ ﺭﺍ ﺧﻮﺍﻧﺪﻩ ﻭ ﺁﻧﻬﺎ ﺭﺍ ﺑﻪ ﻧﻮﻉ ﺗﻌﻴﻴﻦ ﺷﺪﻩ‬source ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
.‫ ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ‬IEnumerable<TResult> ‫ﺟﺪﻳﺪ ﺍﺯ ﻧﻮﻉ‬

.‫ﻣﺜﺎﻝ‬

ArrayList list = new ArrayList { 1, 3, 2, 3, 1, 8, 13 };

IEnumerable<int> query = list.Cast<int>();

foreach (int i in query)


Console.WriteLine(i);
//output
//1
//3
//2
//3
//3
//1
//8
//13
72‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

ToArray ‫ﻋﻤﻠﮕﺮ‬
‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‬.‫ ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‬T[] ‫ ﺭﺍ ﺑﻪ ﻳﮏ ﺁﺭﺍﻳﻪ‬IEnumerable<T> ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻧﻮﻉ‬
:‫ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static TSource[] ToArray<TSource>(


this IEnumerable<TSource> source);

‫ ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ ﻭ‬TSource ‫ ﺭﺍ ﺗﮏ ﺗﮏ ﺧﻮﺍﻧﺪﻩ ﻭ ﺑﻪ ﻧﻮﻉ‬source ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍ ﺗﻤﺎﻣﻲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬
.‫ ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ‬TSource[] ‫ﺳﭙﺲ ﺩﺭ ﺁﺭﺍﻳﻪ ﺟﺪﻳﺪﻱ ﺍﺯ ﻧﻮﻉ‬

.‫ﻣﺜﺎﻝ‬

List<int> numbers = new List<int> { 1, 3, 2, 3, 3, 1, 8, 13 };

int[] query = numbers.ToArray();

foreach (int i in query)


Console.WriteLine(i);

//output
//1
//3
//2
//3
//3
//1
//8
//13
‫‪www.AliAghdam.ir‬‬ ‫ﺻﻔﺤﻪ ‪ | 73‬ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬

‫ﻋﻤﻠﮕﺮ ‪ToList‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻋﻨﺎﺻﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻧﻮﻉ >‪ IEnumerable<T‬ﺭﺍ ﺑﻪ ﻳﮏ ﻣﺠﻤﻮﻋﻪ >‪ List<T‬ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‪ .‬ﻓﺮﻡ ﮐﻠﻲ‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‪:‬‬

‫(>‪public static List<TSource> ToList<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺩﺭ ﺯﻣﺎﻥ ﺍﺟﺮﺍ ﺗﻤﺎﻣﻲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺭﺍ ﺗﮏ ﺗﮏ ﺧﻮﺍﻧﺪﻩ ﻭ ﺩﺭ ﺑﻪ ﻧﻮﻉ ‪ TSource‬ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ ﻭ‬
‫ﺳﭙﺲ ﺩﺭ ﻣﺠﻤﻮﻋﻪ ﺟﺪﻳﺪﻱ ﺍﺯ ﻧﻮﻉ >‪ List<TSource‬ﻗﺮﺍﺭ ﻣﻲ ﺩﻫﺪ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫;} ‪int[] numbers = { 1, 3, 2, 3, 3, 1, 8, 13‬‬

‫;)(‪List<int> query = numbers.ToList‬‬

‫)‪foreach (int i in query‬‬


‫;)‪Console.WriteLine(i‬‬

‫‪//output‬‬
‫‪//1‬‬
‫‪//3‬‬
‫‪//2‬‬
‫‪//3‬‬
‫‪//3‬‬
‫‪//1‬‬
‫‪//8‬‬
‫‪//13‬‬
74‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

ToDictionary ‫ﻋﻤﻠﮕﺮ‬
‫ ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ‬.‫ ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‬Dictionary<TKey, TSource> ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻳﮏ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ ﻧﻮﻉ‬
:‫ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬

public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector);

public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IEqualityComparer<TKey> comparer);

public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector);

public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector,
IEqualityComparer<TKey> comparer);

Dictionary<TKey , ‫ﺭﺍ ﺗﮏ ﺗﮏ ﺷﻤﺎﺭﺵ ﮐﺮﺩﻩ ﻭ ﻳﮏ ﻧﻮﻉ ﺟﺪﻳﺪ ﺍﺯ‬ source ‫ﺩﺭﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻪ‬

Key ‫ ﺍﺭﺯﻳﺎﺑﻲ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﻣﻘﺪﺍﺭ‬keySelector ‫ ﺭﺍ ﺑﻮﺳﻴﻠﻪ ﺗﺎﺑﻊ‬source ‫ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ ﻭ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬TSource>

‫ ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺘﻪ‬Value ‫ ﻭ ﻳﺎ ﻫﻤﺎﻥ‬TSource ‫ ﺭﺍ ﺗﻮﻟﻴﺪ ﻣﻲ ﮐﻨﺪ ﺳﭙﺲ ﻣﻘﺪﺍﺭ ﺁﻥ ﻋﻨﺼﺮ ﺑﻪ ﻋﻨﻮﺍﻥ‬Dictionary ‫ﺑﺮﺍﻱ ﻣﺠﻤﻮﻋﻪ‬
. ...‫ﻣﻲ ﺷﻮﺩ ﻭ ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ‬

.‫ ﺍﻣﮑﺎﻥ ﺗﻌﻴﻴﻦ ﻳﮏ ﺗﺎﺑﻊ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ ﺳﻔﺎﺭﺷﻲ ﺭﺍ ﺗﻌﻴﻴﻦ ﻣﻲ ﮐﻨﺪ‬comparer ‫ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﭘﺎﺭﺍﻣﺘﺮ‬

.‫ ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ‬Value ‫ ﻭ ﻳﺎ ﻫﻤﺎﻥ‬TSource ‫ ﻣﻲ ﺗﻮﺍﻥ ﺑﺮﺍﻱ ﺗﻌﻴﻴﻦ ﻧﻮﻉ‬elementSelector ‫ﺩﺭ ﻓﺮﻡ ﺳﻮﻡ ﺍﺯ ﭘﺎﺭﺍﻣﺘﺮ‬

‫ ﻣﻲ ﺗﻮﺍﻥ ﻧﻮﻉ‬elementSelector ‫ﻓﺮﻡ ﺁﺧﺮ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻲ ﺍﺯ ﻓﺮﻡ ﻫﺎﻱ ﺩﻳﮕﺮ ﺍﺳﺖ ﻳﻌﻨﻲ ﺩﺭ ﺁﻥ ﺑﻮﺳﻴﻠﻪ‬
.‫ ﻣﻲ ﺗﻮﺍﻥ ﺗﺎﺑﻊ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ ﺳﻔﺎﺭﺷﻲ ﺭﺍ ﺗﻌﻴﻴﻦ ﮐﺮﺩ‬comparer ‫ ﺭﺍ ﺗﻌﻴﻴﻦ ﮐﺮﺩ ﻭ ﺑﻮﺳﻴﻠﻪ ﭘﺎﺭﺍﻣﺘﺮ‬TSource

.‫ﻣﺜﺎﻝ‬

var customersDictionary =
customers
.ToDictionary(c => c.Name,
c => new { c.Name, c.City });
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬75 ‫ﺻﻔﺤﻪ‬

ToLookup ‫ﻋﻤﻠﮕﺮ‬
‫ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﮐﻠﻲ‬.‫ ﻣﻮﺭﺩ ﺍﺳﺘﻔﺎﺩﻩ ﻗﺮﺍﺭ ﻣﻲ ﮔﻴﺮﺩ‬Lookup<K, T> ‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﺮﺍﻱ ﺗﺒﺪﻳﻞ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﻳﺎ ﻟﻴﺴﺖ ﺑﻪ ﻧﻮﻉ‬
:‫ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬Lookup<K,T>

public class Lookup<K, T> : IEnumerable<IGrouping<K, T>>


{
public int Count { get; }
public IEnumerable<T> this[K key] { get; }
public bool Contains(K key);
public IEnumerator<IGrouping<K, T>> GetEnumerator();
}

‫ ﺍﺷﺎﺭﻩ ﮐﻨﺪ ﮐﻪ ﺍﻳﻦ ﺍﻣﮑﺎﻥ ﻓﺮﺍﻫﻢ ﺳﺎﺧﺘﻦ ﺳﺎﺧﺘﺎﺭ‬T ‫ﺍﻳﻦ ﺭﺍﺑﻂ ﺍﻳﻦ ﺍﻣﮑﺎﻥ ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﺪ ﻳﮏ ﮐﻠﻴﺪ ﻣﻲ ﺗﻮﺍﻧﺪ ﺑﻪ ﭼﻨﺪﻳﻦ‬
.‫ ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﺪ‬one-to-many

:‫ ﺩﺍﺭﻱ ﭼﻬﺎﺭ ﻓﺮﻡ ﮐﻠﻲ ﺑﻪ ﺻﻮﺭﺕ ﺯﻳﺮ ﺍﺳﺖ‬ToLookup ‫ﻋﻤﻠﮕﺮ‬

public static Lookup<TKey, TSource> ToLookup<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector);

public static Lookup<TKey, TSource> ToLookup<TSource, TKey>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IEqualityComparer<TKey> comparer);

public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector);

public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(


this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector,
IEqualityComparer<TKey> comparer);

Lookup<TKey , ‫ ﺭﺍ ﺗﮏ ﺗﮏ ﺷﻤﺎﺭﺵ ﮐﺮﺩﻩ ﻭ ﻳﮏ ﻧﻮﻉ ﺟﺪﻳﺪ ﺍﺯ‬source ‫ﺩﺭﻓﺮﻡ ﻧﺨﺴﺖ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻪ‬
Key ‫ ﺍﺭﺯﻳﺎﺑﻲ ﻣﻲ ﺷﻮﻧﺪ ﻭ ﻣﻘﺪﺍﺭ‬keySelector ‫ ﺭﺍ ﺑﻮﺳﻴﻠﻪ ﺗﺎﺑﻊ‬source ‫ ﺍﻳﺠﺎﺩ ﻣﻲ ﮐﻨﺪ ﻭ ﺳﭙﺲ ﻋﻨﺎﺻﺮ ﻣﺠﻤﻮﻋﻪ‬TSource>

‫ ﺩﺭ ﻧﻈﺮ ﮔﺮﻓﺘﻪ‬Value ‫ ﻭ ﻳﺎ ﻫﻤﺎﻥ‬TSource ‫ ﺭﺍ ﺗﻮﻟﻴﺪ ﻣﻲ ﮐﻨﺪ ﺳﭙﺲ ﻣﻘﺪﺍﺭ ﺁﻥ ﻋﻨﺼﺮ ﺑﻪ ﻋﻨﻮﺍﻥ‬Lookup ‫ﺑﺮﺍﻱ ﻣﺠﻤﻮﻋﻪ‬
. ...‫ﻣﻲ ﺷﻮﺩ ﻭ ﺑﻪ ﻫﻤﻴﻦ ﺗﺮﺗﻴﺐ‬
‫|ﺻﻔﺤﻪ‪76‬‬ ‫‪LINQ‬‬ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ ‫‪www.AliAghdam.ir‬‬

‫ﺩﺭ ﻓﺮﻡ ﺩﻭﻡ ﭘﺎﺭﺍﻣﺘﺮ ‪ comparer‬ﺍﻣﮑﺎﻥ ﺗﻌﻴﻴﻦ ﻳﮏ ﺗﺎﺑﻊ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ ﺳﻔﺎﺭﺷﻲ ﺭﺍ ﺗﻌﻴﻴﻦ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﺩﺭ ﻓﺮﻡ ﺳﻮﻡ ﺍﺯ ﭘﺎﺭﺍﻣﺘﺮ ‪ elementSelector‬ﻣﻲ ﺗﻮﺍﻥ ﺑﺮﺍﻱ ﺗﻌﻴﻴﻦ ﻧﻮﻉ ‪ TSource‬ﻭ ﻳﺎ ﻫﻤﺎﻥ ‪ Value‬ﺍﺳﺘﻔﺎﺩﻩ ﮐﺮﺩ‪.‬‬

‫‪ elementSelector‬ﻣﻲ ﺗﻮﺍﻥ ﻧﻮﻉ‬ ‫ﻓﺮﻡ ﺁﺧﺮ ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻣﺠﻤﻮﻋﻲ ﺍﺯ ﻓﺮﻡ ﻫﺎﻱ ﺩﻳﮕﺮ ﺍﺳﺖ ﻳﻌﻨﻲ ﺩﺭ ﺁﻥ ﺑﻮﺳﻴﻠﻪ‬
‫‪ TSource‬ﺭﺍ ﺗﻌﻴﻴﻦ ﮐﺮﺩ ﻭ ﺑﻮﺳﻴﻠﻪ ﭘﺎﺭﺍﻣﺘﺮ ‪ comparer‬ﻣﻲ ﺗﻮﺍﻥ ﺗﺎﺑﻊ ﻣﻘﺎﻳﺴﻪ ﮐﻨﻨﺪﻩ ﺳﻔﺎﺭﺷﻲ ﺭﺍ ﺗﻌﻴﻴﻦ ﮐﺮﺩ‪.‬‬

‫ﻣﺜﺎﻝ‪.‬‬

‫= ‪var ordersByProduct‬‬
‫‪( from c in customers‬‬
‫‪from o in c.Orders‬‬
‫) ‪select o‬‬
‫;)‪.ToLookup(o => o.OrderID‬‬

‫‪Console.WriteLine("\n\nNumber of orders for Product 1: {0}\n",‬‬


‫;))(‪ordersByProduct[1].Count‬‬

‫ﻋﻤﻠﮕﺮ ‪AsEnumerable‬‬
‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺭﺍ ﺑﻪ ﻳﮏ ﻣﺠﻤﻮﻋﻪ ﺍﺯ ﻧﻮﻉ >‪ IEnumerable<TSource‬ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‪ .‬ﻓﺮﻡ ﮐﻠﻲ ﺍﻳﻦ ﻋﻤﻠﮕﺮ‬
‫ﺑﻪ ﺍﻳﻦ ﺻﻮﺭﺕ ﺍﺳﺖ‪:‬‬

‫(>‪public static IEnumerable<TSource> AsEnumerable<TSource‬‬


‫;)‪this IEnumerable<TSource> source‬‬

‫ﺍﻳﻦ ﻋﻤﻠﮕﺮ ﺑﻪ ﺳﺎﺩﮔﻲ ﻣﺠﻤﻮﻋﻪ ‪ source‬ﺭﺍ ﺑﻪ ﻧﻮﻉ >‪ IEnumerable<TSource‬ﺗﺒﺪﻳﻞ ﻣﻲ ﮐﻨﺪ‪.‬‬

‫ﺍﻳﻦ ﺩﺳﺘﻪ ﺍﺯ ﻋﻤﻠﮕﺮ ﻫﺎ ﺑﻪ ﺍﺻﻄﻼﺡ ”‪ “conversion on the fly‬ﺧﻮﺍﻧﺪﻩ ﻣﻲ ﺷﻮﻧﺪ ﮐﻪ ﺍﻳﻦ ﺍﻣﮑﺎﻥ ﺭﺍ ﻓﺮﺍﻫﻢ ﻣﻲ ﮐﻨﻨﺪ ﮐﻪ‬
‫‪Customers‬‬ ‫ﺑﺘﻮﺍﻥ ﺗﻮﺍﺑﻊ ﺗﻮﺳﻌﻪ ﻋﺎﻡ ﺭﺍ ﺑﺮ ﺭﻭﻱ ﻧﻮﻉ ﻫﺎﻱ ﮐﻪ ﺗﻮﺍﺑﻌﻲ ﺑﺎ ﻫﻤﺎﻥ ﻧﺎﻡ ﺩﺍﺭﻧﺪ‪ ،‬ﺍﺟﺮﺍ ﻧﻤﻮﺩ‪ .‬ﺑﻪ ﻋﻨﻮﺍﻥ ﻣﺜﺎﻝ ﮐﻼﺱ‬
‫ﺭﺍ ﺑﺎ ﭘﻴﺎﺩﻩ ﺳﺎﺯﻱ ﺯﻳﺮ ﮐﻪ ﻳﮏ ﺗﺎﺑﻊ ﺗﻮﺳﻌﻪ ‪ Where‬ﺑﺮﺍﻱ ﺁﻥ ﺗﻌﺮﻳﻒ ﺷﺪﻩ‪ ،‬ﺩﺭ ﻧﻈﺮ ﺑﮕﻴﺮﻳﺪ‪.‬‬

‫>‪public class Customers : List<Customer‬‬


‫{‬
‫)‪public Customers(IEnumerable<Customer> items‬‬
‫)‪: base(items‬‬
‫{‬
‫}‬
www.AliAghdam.ir ‫ | ﻓﺼﻞ ﺳﻮﻡ – ﻋﻤﻠﮕﺮﻫﺎﻱ ﺍﺳﺘﺎﻧﺪﺍﺭﺩ ﭘﺮﺱ ﻭ ﺟﻮ‬77 ‫ﺻﻔﺤﻪ‬

public static class CustomersExtension


{
public static Customers Where(this Customers source,
Func<Customer, Boolean> predicate)
{
Customers result = new Customers(source);
Console.WriteLine("Custom Where extension method");
foreach (var item in source)
{
if (predicate(item))
result.Add(item);
}
return result;
}
}

‫ﻣﺘﺪ ﻧﺘﻮﺳﻌﻪ ﺟﺪﻳﺪ ﺍﺟﺮﺍ ﺧﻮﺍﻫﺪ‬، ‫ ﺍﻧﺠﺎﻡ ﺩﻫﻴﻢ‬Customers ‫ﺣﺎﻻ ﺍﮔﺮ ﺑﺨﻮﺍﻫﻴﻢ ﭘﺮ ﺳﻮ ﺟﻮﻱ ﺑﺮ ﺭﻭﻱ ﻳﮏ ﻧﻤﻮﻧﻪ ﺍﺯ ﺷﻲﺀ‬
:‫ ﺑﻪ ﻣﺜﺎﻝ ﺯﻳﺮ ﺩﻗﺖ ﮐﻨﻴﺪ‬.‫ ﻧﻤﻲ ﺗﻮﺍﻥ ﺍﺳﺘﻔﺎﺩﻩ ﻧﻤﻮﺩ‬Where ‫ﺷﺪ ﻭ ﺍﺯ ﻣﺘﺪ‬

List<Customer> customers = new List<Customer>()


{
new Customer(){Name="Ali",Family="Aghdam",Country="iran",CustomerID =0},
new Customer(){Name="Majid",Family="Shah Mohammadi",Country="iran",CustomerID=1}
};

Customers customersList = new Customers(customers);

var expr =
from c in customersList
where c.Country == "iran"
select c;

foreach (var item in expr)


{
Console.WriteLine(item);
}

//output
//Custom Where extension method
//Name = Ali , Family = Aghdam , CustomerID = 0
//Name = Vali , Family = piriZadeh , CustomerID =1
78‫|ﺻﻔﺤﻪ‬ LINQ ‫ﻣﺮﺟﻊ ﻳﺎﺩﮔﻴﺮﻱ‬ www.AliAghdam.ir

‫ ﻧﻴﺎﺯ ﺑﻪ ﺍﺳﺘﻔﺎﺩﻩ ﺍﺯ ﻋﻤﻠﮕﺮ‬،‫ ﺍﺟﺮﺍ ﮐﻨﻴﺪ‬Customers ‫ ﺭﺍ ﺑﺮﺭﻭﻱ‬LINQ ‫ ﻣﺮﺑﻮﻁ ﺑﻪ‬Where ‫ﺣﺎﻝ ﺍﮔﺮ ﺑﺨﻮﺍﻫﻴﺪ ﮐﻪ ﻣﺘﺪ ﻋﺎﻡ‬
.‫ ﺍﺳﺘﻔﺎﺩﻩ ﺷﺪﻩ ﺍﺳﺖ‬Customers ‫ ﺑﺮ ﺭﻭﻱ‬Where ‫ ﺩﺭ ﭘﺮﺱ ﻭ ﺟﻮﻱ ﺯﻳﺮ ﺍﺯ ﻣﺘﺪ ﻋﺎﻡ‬.‫ ﺧﻮﺍﻫﻴﺪ ﮐﺮﺩ‬AsEnumerable

List<Customer> customers = new List<Customer>()


{
new Customer(){Name="Ali",Family="Aghdam",Country="iran",CustomerID =0},
new Customer(){Name="Majid",Family="Shah
Mohammadi",Country="iran",CustomerID=1}
};

Customers customersList = new Customers(customers);

var expr =
from c in customersList.AsEnumerable()
where c.Country == "iran"
select c;

foreach (var item in expr)


{
Console.WriteLine(item);
}

//output
//Name = Ali , Family = Aghdam , CustomerID = 0
//Name = Vali , Family = piriZadeh , CustomerID =1

You might also like