www.udmish.cn
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
1
2
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻣﯘﻧﺪﻩﺭﯨﺠﻪ ﺋﺎﺗﺎﻟﻐﯘﻻﺭ ﺋﯩﺰﺍﮬﺎﺗﻰ 5 ................................................................................ ﺋﯩﻜﻜﯩﻨﭽﻰ ﺑﺎﺏ C#ﺗﯩﻠﯩﻨﯩﯔ ﺧﯘﺳﯘﺳﯩﻴﻪﺗﻠﯩﺮﻯ 10 ...................................................... C# 2.0ﮔﻪ ﻗﺎﻳﺘﺎ ﻧﻪﺯﻩﺭ 10 ......................................................................... ﻛﯚﭘﻤﺎﺳﻠﯩﻖ 10 ..................................................................................... ﻣﯘﯞﻩﻗﻘﻪﺗﻠﻪﺭ 13 .................................................................................... ﻧﺎﻣﺴﯩﺰ ﻣﯧﺘﻮﺩ 15 ................................................................................... Enumeratorsﯞﻩ 17 ....................................................................... Yield C# 3.0ﻧﯩﯔ ﺧﯘﺳﯘﺳﯩﻴﻪﺗﻠﯩﺮﻯ22 ................................................................... varﺧﺎﺱ ﺳﯚﺯﻯ 22 ................................................................................ ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ 23 ............................................................................... ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﻰ ﺩﻩﺳﻠﻪﭘﻠﻪﺷﺘﯜﺭﯛﺵ ﺋﯩﭙﺎﺩﯨﺴﻰ 28 ....................................................... ﻧﺎﻣﺴﯩﺰ ﺗﯩﭗ 31 .................................................................................... Queryﺋﯩﭙﺎﺩﯨﺴﻰ )ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ( 33 ....................................................... ﺗﯚﺗﯩﻨﭽﻰ ﺑﺎﺏ
Linqﮔﺮﺍﻣﻤﺎﺗﯩﻜﯧﺴﯩﺪﯨﻦ ﺋﺎﺳﺎﺱ 35 ..................................................
LINQﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻠﯩﺮﻯ )35 ...................................................... (LINQ Queries ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﺴﻰ 35 ...................................................................... ﺗﻮﻟﯘﻕ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ 38 ................................................................... ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ40 .................................................................... Whereﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ 40 .......................................................................... ﺋﻪﻣﻪﻟﯩﻠﻪﺷﺘﯜﺭﯛﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )42 ....................................... (Projection Operators SelectManyﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ43 ..................................................................... Orderingﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﺳﻮﺭﺗﻼﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ( 45 ........................................... OrderByﺑﯩﻠﻪﻥ OrderByDescendingﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ 45 ............................................ ThenByﺑﯩﻠﻪﻥ ThenByDescendingﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ 46 ............................................. Reverceﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ )ﻛﯚﻣﺘﯜﺭﯛﺵ( 48 ............................................................ Groupingﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﮔﯘﺭﭘﯩﻼﺵ( 48 ......................................................... Joinﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﮬﻪﻣﺪﻩﻡ( 51 .................................................................
3
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
) Joinﮬﻪﻣﺪﻩﻡ ( 51 ................................................................................ GroupJoinﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ 53 ...................................................................... Setﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﺗﻮﭘﻼﻡ(55 .................................................................... Distinctﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ )ﺗﻪﻛﺮﺍﺭﻧﻰ ﺗﺎﺯﯨﻼﺵ( 55 ..................................................... 56 ................................................................ Union, Intersect, and Except Aggregateﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﺟﻪﻣﻠﻪﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ( 59 .......................................... Countﯞﻩ LongCountﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ 59 ........................................................... Sumﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ )ﻳﯩﻐﯩﻨﺪﺍ(60 ................................................................... 63 .................................................................................Min and Max Averageﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ 65 ........................................................................ Generationﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﻗﯘﺭﻏﯘﭺ( 67 .......................................................... ) Rangeﺩﺍﺋﯩﺮﻩ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( 67 .................................................................. ) Repeatﺗﻪﻛﺮﺍﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( 68 ................................................................. ) Emptyﻗﯘﺭﯗﻕ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( 69 ................................................................. Quantifiersﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﻣﯩﻘﺪﺍﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ(69 ............................................ Anyﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ 69 ............................................................................ ) Allﮬﻪﻣﻤﻪ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( 70 ..................................................................... ) Containsﺑﺎﺭﻣﯘ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( 70 ................................................................ Partitioningﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﭘﺎﺭﭼﯩﻼﺵ( 71 ....................................................... ) Takeﻧﻰ -ﺋﯧﻠﯩﺶ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ(72 .............................................................. ) TakeWhileﭼﺎﻏﺪﺍ -ﺋﯧﻠﯩﺶ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( 73 ..................................................... Skipﺑﯩﻠﻪﻥ 74 ........................................................................ SkipWhile ﺋﯧﻠﯧﻤﯧﻨﺖ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ 75 ....................................................................... ) Firstﺗﯘﻧﺠﻰ ﻣﻪﺷﻐﯘﻻﺗﯩﭽﯩﺴﻰ( 75 .................................................................. 75 ................................................................................ FirstOrDefault Lastﺑﯩﻠﻪﻥ 76 .................................................................... LastOrDefault 76 ........................................................................................ Single 77 .............................................................................. SingleOrDefault ElementAtﺑﯩﻠﻪﻥ 77 ....................................................... ElementAtOrDefault
4
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
78 ............................................................................... DefaultIfEmpty ﺑﺎﺷﻘﺎ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ 80 ............................................................................. ) Concatﺋﯘﻻﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( 80 ................................................................. 81 ............................................................................... SequenceEqual ﻛﯧﭽﯩﻜﺘﯜﺭﯛﻟﻤﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻨﯩﺸﻰ ﯞﻩ ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ ﭼﺎﺭﯨﺴﻰ 82 ......................... ﻛﯧﭽﯩﻜﺘﯜﺭﯛﻟﻤﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻨﯩﺸﻰ 82 ..................................................... ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ ﭼﺎﺭﯨﺴﻰ 84 ....................................................................... ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ 85 ................................................................... ToArrayﺑﯩﻠﻪﻥ 86 ........................................................................ ToList 88 ................................................................................. ToDictionary 89 .................................................................................... ToLookup OfTypeﺑﯩﻠﻪﻥ 91 ........................................................................... Cast
5
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﺎﺗﺎﻟﻐﯘﻻﺭ ﺋﯩﺰﺍﮬﺎﺗﻰ ﻣﻪﺯﻛــﯘﺭ ﻛﯩﺘــﺎﺑﻨﻰ ﺋﻮﻗــﯘﺵ ﺟﻪﺭﻳﺎﻧﯩــﺪﺍ ﭘــﺎﺕ-ﭘــﺎﺕ ﻛﯜﻟــﯜﭖ ﺗﯘﺭﯨــﺪﯨﻐﺎﻧﻠﯩﻘﯩﯖﯩﺰﻏﺎ ﺋﯩــﺸﻪﻧﭽﯩﻢ ﻛﺎﻣﯩــﻞ. ﺋﻪﺳـــﻠﯩﺪﻩ ﺋﺎﺗـــﺎﻟﻐﯘﻻﺭ ﺋﯩﺰﺍﮬـــﺎﺗﻰ ﻣﻪﻥ ﻳﺎﺯﯨـــﺪﯨﻐﺎﻥ ﻣﻪﺯﻣـــﯘﻥ ﺋﻪﻣﻪﺱ ﺋﯩـــﺪﻯ ،ﻟـــﯧﻜﯩﻦ ﻛﻮﻣﭙﯩﻴـــﯘﺗﯧﺮ ﺳﺎﮬﻪﺳــﯩﺪﯨﻜﻰ ﻛﻪﺳــﭙﯩﻲ ﺋﺎﺗــﺎﻟﻐﯘﻻﺭﻧﻰ ﺋﺎﺗــﺎﻟﻐﯘ ﺋﯩﺰﺍﮬــﺎﺕ ﻟــﯘﻏﻪﺗﻠﯩﺮﯨﻤﯩﺰﺩﯨﻦ ﺗﻮﻟــﯘﻕ ﺗﺎﭘﺎﻻﻳــﺪﯨﻐﺎﻥ ﺑﻮﻟﯘﺷـــﯩﻤﯩﺰﻏﺎ ﻳﻪﻧﻪ ﺑﯩـــﺮ ﻣﻪﺯﮔﯩـــﻞ ﻛﯧﺘﯩـــﺪﯨﻐﺎﻥ ﺑﻮﻟﻐﺎﭼﻘـــﺎ ،ﺑﯩـــﺮ ﻗﯩـــﺴﯩﻢ ﻛﻪﺳـــﭙﻰ ﺋﺎﺗـــﺎﻟﻐﯘﻻﺭﻧﻰ ﺟﯚﻳﻠﯜﺷــﯩﻤﯩﺰﮔﻪ ﺗــﻮﻏﺮﺍ ﻛﻪﻟــﺪﻯ .ﺷــﯘﯕﺎ ﻛﯩﺘــﺎﺏ ﻣﻪﺯﻣﯘﻧﯩــﺪﺍ ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﺳــﯚﺯﻟﻪﺭﻧﻰ ﺋــﯘﭼﺮﺍﺗﻘﯩﻨﯩﯖﯩﺰﺩﺍ ﻛﯜﻟﮕﻪﭺ ﺗﻮﻏﺮﺍ ﭼﯜﺷﯩﻨﻪﺭﺳﯩﺰ .ﺋﺎﺗﺎﻟﻐﯘ ﺗﻪﺭﺟﯩﻤﻪ ﺧﯩﺰﻣﯩﺘﯩﺪﻩ ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﭘﯩﻜﯩﺮﻟﻪﻧﻰ ﺑﻪﺭﮔﻪﻥ ﺋﯚﻣﻪﺭﺟـﺎﻥ ﺋﺎﺑﺪﯗﺭﺍﺧﻤﺎﻥ )ﺋﯘﭼﻘﯘﻥ( ﺋﻪﭘﻪﻧﺪﯨﮕﻪ ﻛﯚﭖ ﺗﻪﺷﻪﻛﻜﯜﺭ. ﻛﯚﭘﻤﺎﺱ \ ﻛﯚﭘﻤﺎﺳﻠﯩﻖ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ ،generic :ﺧﻪﻧﺰﯗﭼﯩﺴﻰ 泛型 :ﺑﻮﻟـﯘﭖ ،ﺋﻮﺭﺗـﺎﻕ ﺗﯩﭙﻠﯩـﭗ، ﮬﻪﻣﻤﯩــﮕﻪ ﻣــﺎﺱ ﻛﯧﻠﯩــﺪﯨﻐﺎﻥ ﺩﯦــﮕﻪﻥ ﻣﻪﻧﯩﻠﻪﺭﻧــﻰ ﺑﯧﺮﯨــﺪﯗ .ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ ﻧﯘﺧﺘﯩــﺴﯩﺪﯨﻦ ﭼﯜﺷــﻪﻧﮕﻪﻧﺪﻩ، genericﺗﯩــﭗ ﺑﻮﻟــﺴﺎ ﻛﻮﻧﻜﺮﯦــﺖ ﺑﯩــﺮ ﺗﯩﭙﻨــﻰ ﻛﯚﺭﺳــﻪﺗﻤﻪﻱ ﺑﻪﻟﻜــﻰ ﺗﯩﭙــﻰ ﻣﻪﺷــﻐﯘﻻﺗﻘﺎ ﻗﺎﺗﻨﺎﺷــﻘﯘﭼﻰ ﻛﻮﻧﻜﺮﯦﺖ ﺗﯩﭗ ﺗﻪﺭﯨﭙﯩﺪﯨﻦ ﺑﻪﻟﮕﯩﻠﯩﻨﯩﺪﯨﻐﺎﻥ ﺋﯧﻨﯩﻘﺴﯩﺰ ،ﮬﻪﻣﻤﯩﮕﻪ ﻣـﺎﺱ ﻛﯧﻠﯩـﺪﯨﻐﺎﻥ ﺗﯩـﭗ ﺑﻮﻟﻐﺎﭼﻘـﺎ، ﺋﯘﻧﯩﯔ ﮬﻪﻣﻤﯩﮕﻪ ﻣـﺎﺱ ﻛﯧﻠﯩـﺪﯨﻐﺎﻥ ﺋﺎﻻﮬﯩـﺪﯨﻠﯧﻜﯩﻨﻰ ﮔﻪﯞﺩﯨﻠﻪﻧـﺪﯛﺭﯛﺵ ﻳﯜﺯﯨـﺴﯩﺪﯨﻦ ﺋﯘﻧﯩـﯔ ﺳـﯜﭘﻪﺕ ﺷﻪﻛﻠﻰ »ﻛﯚﭘﻤﺎﺱ« ،ﺋﯩﺴﯩﻢ ﺷﻪﻛﻠﻰ »ﻛﯚﭘﻤﺎﺳﻠﯩﻖ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ. ﻛــﻮﺩ ﻗــﺎﭘﭽﯘﻗﻰ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩــﺴﻰ ،Code Container :ﺧﻪﻧﺰﯗﭼﯩــﺴﻰ 代码容器 :ﺑﻮﻟــﯘﭖ ،ﻣﻪﻟــﯘﻡ ﻛــﻮﺩﻻﺭﻧﻰ ﺋﯚﺯﯨــﺪﻩ ﺋﯧﻠﯩــﭗ ﻳﯜﺭﻩﻟﻪﻳــﺪﯨﻐﺎﻥ ﻛــﻮﺩ ﺑــﯚﻟﯧﻜﯩﻨﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ Container .ﻳﻪﻧــﻰ 容器
ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﺳﺎﮬﻪﺳﯩﺪﻩ ﻛﯚﭖ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯨﻐﺎﻥ ﺋﺎﺗﺎﻟﻐﯘ ﺑﻮﻟﯘﭖ ،ﺑﯩﺮ ﺗﯜﺭﻛﯜﻡ ﻧﻪﺭﺳﯩﻠﻪﻧﻰ ﺋﯚﺯﯨـﺪﻩ ﺗﯘﺗـﯘﭖ
ﺗﯘﺭﺍﻻﻳﺪﯨﻐﺎﻥ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﻰ ﻛﯚﭘﯜﺭﻩﻙ ﻣﯘﺷﯘ ﺳﯚﺯ ﺑﯩﻠﻪﻥ ﺋﺎﺗﺎﻳﺪﯗ .ﻣﻪﺳـﯩﻠﻪﻥControl Container ، )ﻛﻮﻧﺘﺮﻭﻝ ﻗﺎﭘﭽﯘﻗﻰ( ﺩﯦﮕﻪﻧﺪﻩﻙ .ﺑﯘ ﺧﯩﻞ ﺋﺎﻻﮬﯩـﺪﯨﻠﯩﻜﻨﻰ ﺋﯩﭙـﺎﺩﯨﻠﻪﺵ ﺋﯜﭼـﯜﻥ »ﻛـﻮﺩ ﺳـﺎﻧﺪﯗﻗﻰ«، »ﻛﻮﺩ ﺋﯧﻠﯩﭗ ﻳﯜﺭﮔﯜﭺ« ﺩﯦﮕﻪﻧﺪﻩﻙ ﺑﯩﺮ ﻗﯩﺴﯩﻢ ﺳـﯚﺯ ﺑﯩﺮﯨﻜﻤﯩﻠﯩﺮﻧـﻰ ﺋـﻮﻳﻼﭖ ﺑـﺎﻗﺘﯩﻢ ،ﻟـﯧﻜﯩﻦ »ﻛـﻮﺩ ﻗﺎﭘﭽﯘﻗﻰ« ﺩﻩﭖ ﺋﺎﺗﺎﺵ ﺋﻪﯓ ﻣﯘﯞﺍﭘﯩﻖ ﺗﯘﻳﯘﻟﺪﻯ. ﭼـﺎﻗﯩﺮﻏﯘ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩـﺴﻰ ،callback :ﺧﻪﻧﺰﯗﭼﯩـﺴﻰ 回调 :ﺑﻮﻟــﯘﭖ ،ﭼـﺎﻗﯩﺮﯨﺶ ﺩﯦـﮕﻪﻥ ﻣﻪﻧﯩــﺪﻩ. ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺪﺍ ﺑﯩﺮ ﺩﺍﻧﻪ callbackﻣﻪﻟﯘﻡ ﻛﻮﺩ ﺑﯚﻟﯩﻜﯩﮕﻪ ﺗﻮﻏﯘﺭﻻﻧﻐﺎﻥ ﺋﯩـﺴﺘﺮﯦﻠﻜﯩﻐﺎ ﺋﯘﻻﻧﻐـﺎﻥ ﺑﻮﻟﯩـﺪﯗ. callbackﻧﻰ ﺋﯩﺠـﺮﺍ ﻗﯩﻠﯩـﺶ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﺋـﯘ ﺗﻮﻏﯘﺭﻻﻧﻐـﺎﻥ ﻛـﻮﺩ ﺑـﯚﻟﯧﻜﯩﻨﻰ ﺋﯩﺠـﺮﺍ ﻗﯩﻠﻐﯩﻠـﻰ ﺑﻮﻟﯩـﺪﯗ. ﺩﯦﻤﻪﻙ ﺋﯘ ﺋﻪﺷﯘ ﻛﻮﺩ ﺑﯚﻟﯧﻜﯩﻨﯩـﯔ ﭼﺎﻗﯩﺮﻏﯘﭼﯩـﺴﻰ ،ﺷـﯘﯕﺎ ﺋـﯘ »ﭼـﺎﻗﯩﺮﻏﯘ« .ﺑـﯘ ﻣﯘﺷـﯘﻧﺪﺍﻕ ﺋﺎﺗﺎﺷـﻘﺎ ﻳﯧﺘﻪﺭﻟﯩﻚ ﺋﺎﺳﺎﺱ ﺑﯩﻠﯩﻨﺪﻯ. ﺩﻩﺳــﺘﻪ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩــﺴﻰ ،stack :ﺧﻪﻧﺰﯗﭼﯩــﺴﻰ 栈 :ﺑﻮﻟــﯘﭖ ،ﺷــﻪﻳﺌﯩﻠﻪﺭﻧﯩﯔ ﺋﯜﺳــﺘﯩﻤﯘ-ﺋﯜﺳــﺘﻰ ﺗﯩﺰﯨﻠﻐﺎﻥ ﺩﻩﺳﺘﯩﺴﯩﻨﻰ ﻛﯚﺭﺳﯩﺘﯩﺪﯗ .ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺪﯨﻜﻰ stackﺑﻮﻟﺴﺎ ﺑﯩﺮ ﺧﯩﻞ ﺋﺎﻻﮬﯩﺪﻩ ﺳﺎﻧﻠﯩﻖ ﻣﻪﻟﯘﻣﺎﺕ ﻗﯘﺭﯗﻟﻤﯩﺴﻰ ﺑﻮﻟـﯘﭖ ،ﺋﯘﻧﯩـﯔ ﻗﯘﺭﯗﻟﻤﯩـﺴﻰ ﺧـﯘﺩﺩﻯ ﺗﻪﺧـﺴﻪ ﺗﯩﺰﻏﺎﻧﻐـﺎ ﺋﻮﺧـﺸﺎﻳﺪﯗ .ﻳﻪﻧـﻰ ،ﺗﻪﺧـﺴﯩﻠﻪﺭ ﺑﯩﺮﯨﻨﯩــﯔ ﺋﯜﺳــﺘﯩﮕﻪ ﺑﯩــﺮ ﻗﻮﻳﯘﻟﯩــﺪﯗ .ﺋــﯘﻻﺭﻧﻰ ﺋــﯧﻠﯩﺶ ﺋﯜﭼــﯜﻥ ﺋﻪﯓ ﺗﯚﭘﯩــﺪﯨﻦ ﺑﯩــﺮ-ﺑﯩــﺮﻟﻪﭖ ﺋــﯧﻠﯩﺶ ﻛﯧﺮﻩﻙ ،ﺩﯦﻤﻪﻙ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﺪﺍ ﺗﯩﺰﯨﻠﻐﯩﻨﻰ ﺋﻪﯓ ﺑﺎﺷﺘﺎ ﺋﯧﻠﯩﻨﯩﺪﯗ ،ﺋﻪﯓ ﺑﺎﺷﺘﺎ ﺗﯩﺰﯨﻠﻐﯩﻨﻰ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨـﺪﺍ ﺋﯧﻠﯩﻨﯩﺪﯗ .ﺑﯘ ﺟﻪﺭﻳﺎﻧﻨﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺭﻩﺳﯩﻤﺪﯨﻜﯩﺪﻩﻙ ﺋﯩﭙﺎﺩﯨﻠﻪﺵ ﻣﯘﻣﻜﯩﻦ:
6
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﻪﯓ ﻛﯧﻴﯩﻦ ﺗﯩﺰﯨﻠﻐﺎﻥ ﺗﻪﺧﺴﻪ ﺋﻪﯓ ﺑﯘﺭﯗﻥ ﺗﯩﺰﯨﻠﻐﺎﻥ ﺗﻪﺧﺴﻪ
ﺷﯘﯕﺎ ﺑﯘ ﺧﯩﻞ ﺳﺎﻧﻠﯩﻖ ﻣﻪﻟﯘﻣﺎﺕ ﻗﯘﺭﯗﻟﻤﯩﺴﻰ ﺩﻩﺳﺘﻪ ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ. ﺋﯚﻣﯜﺭ – ﺋﯧﻨﮕﻠﯩﺰﭼﯩـﺪﺍ ،lifetime :ﺧﻪﻧﺰﯗﭼﯩـﺪﺍ 生命周期 :ﺑﻮﻟـﯘﭖ ،ﺋﯚﻣـﯜﺭﻯ ﺩﯦـﮕﻪﻥ ﻣﻪﻧﯩـﺪﻩ .ﺋـﯘ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺪﺍ ﻣﻪﻟﯘﻡ ﺋﯚﺯﮔﻪﺭﮔﯜﭼﻰ ﻣﯩﻘـﺪﺍﺭﻧﯩﯔ ﺋـﯚﺯﻯ ﺗﯘﺭﻏـﺎﻥ ﻛـﻮﺩ ﺑﯚﻟﯩﻜﯩـﺪﻩ ﺋﯜﻧﯜﻣﻠـﯜﻙ ﺑﻮﻻﻻﻳـﺪﯨﻐﺎﻥ ﯞﺍﻗﯩــﺖ ﺋــﯘﺯﯗﻧﻠﯩﻘﯩﻨﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ .ﻣﻪﺳــﯩﻠﻪﻥ ،ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﭘﺮﻭﮔﺮﺍﻣﻤﯩــﺪﺍ ﺋﻮﺧــﺸﯩﻤﯩﻐﺎﻥ ﺋﻮﺭﯗﻧــﺪﺍ ﺋﯧﻨﯩﻘﻼﻧﻐﺎﻥ ﺋﯚﺯﮔﻪﺭﮔﯜﭼﻰ ﻣﯩﻘﺪﺍﺭﻻﺭﻧﯩﯔ ﺋﯜﻧﯜﻣﻠﯜﻙ ﻣﻪﺯﮔﯩﻠﻰ ﺋﻮﺧﺸﺎﺵ ﺑﻮﻟﻤﺎﻳﺪﯗ.
public class MisalClass { public int ozgerguchi1 = 1; public int misalFun() { int ozgerguchi2 = ozgerguchi1 + 1 ; return ozgerguchi2; } }
ﻳــﯘﻗﯩﺮﯨﻘﻰ ﻛــﻮﺩﺩﺍ ozgerguchi1ﻧﯩــﯔ ﺋﯜﻧﯜﻣﻠــﯜﻙ ﻣﻪﺯﮔﯩﻠــﻰ MisalClassﻧﯩﯖﻜــﻰ ﺑﯩــﻠﻪﻥ ﺋﻮﺧــﺸﺎﺵ ﺑﻮﻟﯘﭖ MisalClass ،ﻣﻪﯞﺟﯘﺗﻼ ﺑﻮﻟﯩـﺪﯨﻜﻪﻥ ﺋﯘﻣـﯘ ﻣﻪﯞﺟـﯘﺕ ﺑﻮﻟـﯘﭖ ﺗﯘﺭﺍﻻﻳـﺪﯗ ozgerguchi2 .ﻧﯩـﯔ ﺋﯜﻧﯜﻣﻠﯜﻙ ﻣﻪﺯﮔﯩﻠﻰ ﻗﯩﺴﻘﯩﺮﺍﻕ ﺑﻮﻟـﯘﭖ misalFun ،ﻓﯘﻧﻜﯩﺴﯩﻴﯩـﺴﯩﻨﯩﯔ ﺋﯩﺠﺮﺍﺳـﻰ ﺑﺎﺷﻠﯩﻨﯩـﺸﻰ ﺑﯩﻠﻪﻧـﻼ ﺋﯜﻧﯜﻡ ﺑﻮﻟﯘﺷﻘﺎ ﺑﺎﺷﻼﭖ ،ﺋﯩﺠﺮﺍ ﺗﺎﻣﻼﻣﻼﻧﻐﺎﻧﺪﺍ ﺋﯜﻧﯜﻣﺴﯩﺰﻟﯩﻨﯩﺪﯗ .ﺋﯚﺯﮔﻪﺭﮔـﯜﭼﻰ ﻣﯩﻘـﺪﺍﺭﻻﺭﻧﯩﯔ ﺑـﯘ ﺧﯩـﻞ ﺧﺎﺳﻠﯩﻘﯩﻨﻰ ﺋﯘﻧﯩﯔ »ﺋﯚﻣﺮﻯ« ﺩﻩﭖ ﺋﺎﺗﺎﺵ ﻣﯘﯞﺍﭘﯩﻖ ﺑﯩﻠﯩﻨﺪﻯ. ﺋﯚﺗﻜــﯜﻧﭽﻰ ﻛــﻮﺩ -ﺋﯩﻨﮕﻠﯩﺰﭼﯩــﺴﻰ Code)IL
،(Intermediateﺧﻪﻧﺰﯗﭼﯩــﺴﻰ 中间语言ﺑﻮﻟــﯘﭖ،
.NETﺋﺎﺋﯩﻠﯩﺴﯩﺪﯨﻜﻰ ﺗﯩﻠﻼﺭﺩﺍ ﻳﯧﺰﯨﻠﻐـﺎﻥ ﻛـﻮﺩﻻﺭ ﺋﺎﺧﯩﺮﯨـﺪﺍ ﮬﻪﻣﻤﯩـﺴﯩﮕﻪ ﺋﻮﺭﺗـﺎﻕ ﺑﻮﻟﻐـﺎﻥ ILﺗﯩﻠﯩﻐـﺎ ﺋﺎﻳﻼﻧــﺪﯗﺭﯗﻟﯘﭖ ،ﮬﻪﻗﯩﻘــﻰ ﺋﯩﺠــﺮﺍ ﺑﻮﻟﻐﺎﻧــﺪﺍ ﺋﯘﻣــﯘ ﻳﻪﻧﻪ ﻣﺎﺷــﯩﻨﺎ ﺗﯩﻠﯩﻐــﺎ ﺋﺎﻳﻠﯩﻨﯩــﺪﯗ .ﺋﻪﻣﻪﻟﯩﻴﻪﺗــﺘﻪC# ، ﺑﯩﻠﻪﻥ VB.NETﻳﯧﺰﯨﻠﻐﺎﻥ ﻛـﻮﺩﻻﺭﻧﻰ ﺋـﺎﺭﻻﺵ ﺋﯩﺸﻠﯩﺘﯩـﺸﻜﻪ ﻣـﯘﻣﻜﯩﻦ ﺑﻮﻟﯩـﺪﯨﻐﺎﻧﻠﯩﻘﯩﻨﯩﯔ ﺳـﻪﯞﻩﺑﯩﻤﯘ ﺷﯘ .ﺋﯘ ﺧﺎﺭﺍﻛﺘﯧﺮﯨﮕﻪ ﺋﺎﺳﺎﺳﻪﻥ »ﺋﯚﺗﻜﯜﻧﭽﻰ ﻛﻮﺩ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ.
7
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺗﯩﻠﻼﺭﻏﺎ ﺋﻮﺭﺗﺎﻕ ﺋﯩﺠﺮﺍ ﺳﯘﭘﯩـﺴﻰ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩـﺴﻰ ،Common Language Runtimeﺧﻪﻧﺰﯗﭼﯩـﺴﻰ: 通用语言运行库ﺑﻮﻟﯘﭖ .NET ،ﺋﺎﺋﯩﻠﯩـﺴﯩﺪﯨﻜﻰ ﺗﯩﻠـﻼﺭﺩﺍ ﺗـﯜﺯﯛﻟﮕﻪﻥ ﭘﺮﻭﮔـﺮﺍﻣﻤﯩﻼﺭ ﺋﯩﺠـﺮﺍ ﺑﻮﻟـﯘﺵ ﺋﯜﭼﯜﻥ ﺯﯙﺭﯛﺭ ﺋﺎﺳﺎﺱ ﺑﻮﻟﯩﺪﯨﻐﺎﻥ ﺋﯩﺠﺮﺍ ﺳﯘﭘﯩﺴﯩﺪﯗﺭ .ﺋﯘﻧﯩﯔ ﺧﺎﺭﺍﻛﺘﯧﺮﻯ ﭼﯩﻘﯩﺶ ﻗﯩﻠﯩﻨﯩﭗ »ﺗﯩﻠﻼﺭﻏـﺎ ﺋﻮﺭﺗﺎﻕ ﺋﯩﺠﺮﺍ ﺳﯘﭘﯩﺴﻰ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ. ﺗﯩــﭗ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩــﺴﻰ ،Type :ﺧﻪﻧﺰﯗﭼﯩــﺴﻰ 类型:ﺑﻮﻟــﯘﭖ ،ﺗــﯜﺭﻯ ،ﺗﯩﭙــﻰ ﺩﯦــﮕﻪﻥ ﻣﻪﻧﯩــﻠﻪﺭﺩﻩ. ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺪﯨﻜﻰ Typeﺑﻮﻟـﺴﺎ ﭘﺮﻭﮔﺮﺍﻣﻤﯩـﺪﯨﻜﻰ ﻣﻪﻟـﯘﻡ ﺋﯚﺯﮔﻪﺭﮔـﯜﭼﻰ ﻣﯩﻘـﺪﺍﺭﻧﯩﯔ ﺋﯚﺯﯨـﺪﻩ ﺳـﺎﻧﻼﻧﻐﺎﻥ ﺋﯘﭼﯘﺭﻧﯩـﯔ ﺧـﺎﺭﺍﻛﺘﯧﺮﯨﮕﻪ ﺋﺎﺳﺎﺳـﻪﻥ ﺑﯚﻟـﯜﻧﮕﻪﻥ ﺗﯩﭙﯩﻨــﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﻳـﺪﯗ .ﻟـﯧﻜﯩﻦ ﺋـﯘ (类) Classﺩﯨــﻦ ﭘﻪﺭﻗﻠﯩﻨﯩﺪﯗ. ﺗﯜﺭ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ ،Class[klɑ:s] :ﺧﻪﻧﺰﯗﭼﯩﺴﻰ 类 :ﺑﻮﻟﯘﭖ .ﺗﯩﭗ ،ﺗﯜﺭ ﺩﯦﮕﻪﻥ ﻣﻪﻧﯩﺪﻩ .ﻟـﯧﻜﯩﻦ ﺑﯘ ﺗﯩﭗ (类型)Typeﺑﯩﻠﻪﻥ ﺩﻭﻗﺎﻝ ﻛﯧﻠﯩﭗ ﻗﺎﻟﻐﺎﻧﻠﯩﻘﻰ ﺋﯜﭼﯜﻥ ﺗﯜﺭ ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ .ﺋﯘﻧﯩﯖﺪﯨﻦ ﺑﺎﺷـﻘﺎ project, 项目ﻧﯩﻤﯘ ﺗﯜﺭ ﺩﻩﭖ ﺋﯧﻠﯩﺶ ﻣﯘﯞﺍﭘﯩﻖ ،ﺷﯘﯕﺎ ﺑﯘ ﻛﯩﺘﺎﭘﺘـﺎ »ﺗـﯜﺭ« ﮬﻪﻡ classﮬﻪﻡ project ﺩﯦــﮕﻪﻥ ﻣﻪﻧﯩﻠﻪﺭﻧــﻰ ﺑﯧﺮﯨــﺪﯗ .ﺯﺍﺩﻯ ﻗﺎﻳــﺴﻰ ﻣﻪﻧﯩــﺪﻩ ﻛﻪﻟﮕﻪﻧﻠﯩــﺪﻯ ﺋــﯚﺯﻯ ﺗﯘﺭﯗﺷــﻠﯘﻕ ﻣﻪﺯﻣﯘﻧــﺪﯨﻦ ﻛﻪﻟﺘﯜﺭﯛﯞﯦﻠﯩﺪﯗ. ﻣﯧﺘﻮﺩ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ ،Method['meθəd] :ﺧﻪﻧﺰﯗﭼﯩﺴﻰ 方法,函数 :ﺑﻮﻟـﯘﭖ ،ﭘﺮﻭﮔﺮﺍﻣﻤﯩـﺪﺍ ﺑﯩـﺮ ﺑﯚﻟﻪﻙ ﯞﻩﺯﯨﭙﯩﻨﻰ ﻣﯘﺳﺘﻪﻗﯩﻞ ﺋﻮﺭﯗﻧﻼﻳﺪﯨﻐﺎﻥ ﻛـﻮﺩ ﺑـﯚﻟﯧﻜﯩﻨﻰ ﻛﯚﺭﺳـﯩﺘﯩﺪﯗ .ﺳـﯚﺯ ﻣﻪﻧﯩـﺴﯩﺪﯨﻦ ﺋﺎﻟﻐﺎﻧـﺪﺍ »ﺋﯘﺳﯘﻝ« ﺩﯦﮕﻪﻥ ﻣﻪﻧﺎ ﺑﯧﺮﯨﺪﯗ .ﻟﯧﻜﯩﻦ ﭘﺮﻭﮔﺮﺍﻣﻤﯩـﺪﯨﻜﻰ ﺧﺎﺭﺍﻛﺘﯧﺮﯨـﺪﯨﻦ ﺋﺎﻟﻐﺎﻧـﺪﺍ ﺋـﯘﻧﻰ »ﺋﯘﺳـﯘﻝ« ﺩﻩﭖ ﺋﺎﺗﺎﺵ ﻣﯘﯞﺍﭘﯩﻖ ﺑﯩﻠﯩﻨﻤﯩﮕﻪﭼﻜﻪ ،ﺑﯘ ﻛﯩﺘﺎﺑﺘﺎ ﻣﯧﺘﻮﺩ ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ. ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﻪ – ﺋﯧﻨﮕﯩﻠﯩﺰﭼﯩـﺴﻰ ،Compile [kəm'pail] :ﺧﻪﻧﺰﯗﭼﯩـﺴﻰ 编译 :ﺑﻮﻟـﯘﭖ ،ﻛﻮﻣﭙﻴـﯘﺗﯧﺮ ﺗﯩﻠﯩﺪﺍ ﻳﯧﺰﯨﻠﻐﺎﻥ ﻛﻮﺩﻧﻰ ﺑﺎﺷﻘﺎ ﺑﯩﺮ ﺧﯩﻞ ﻛﻮﻣﭙﻴﯘﺗﯧﺮ ﺗﯩﻠﯩﻐﺎ ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﯩـﺶ ﺟﻪﺭﻳـﺎﻧﯩﻨﻰ ﻛﯚﺭﺳـﯩﺘﯩﺪﯗ )ﺑــﯘ ﻣﻪﺷــﻐﯘﻻﺗﻨﻰ ﻛﯚﭘــﯜﻧﭽﻪ ﺷــﯘ ﻛــﻮﺩﻧﻰ ﻳﺎﺯﻏــﺎﻥ IDEﺋﻮﺭﯗﻧﻼﻳــﺪﯗ( .ﺑــﯘ ﺟﻪﺭﻳــﺎﻧﻨﻰ 编辑ﻳﻪﻧــﻰ ﺗﻪﮬﺮﯨﺮﻟﻪﺵ ﺩﯨﻴﯩﺸﻜﻪ ﺑﻮﻟﻤﺎﻳﺪﯗ .ﻣﻪﺷﻐﯘﻻﺗﻨﯩﯔ ﺟﻪﺭﻳﺎﻥ ﺧﺎﺭﺍﻛﺘﯧﺮﻯ ﭼﯩﻘﯩﺶ ﻗﯩﻠﯩﻨﯩﭗ ﻛﻮﺩ-ﺗﻪﺭﺟﯩـﻤﻪ ﺩﻩﭖ ﺋﯧﻠﯩﻨــﺪﻯ .ﻛــﻮﺩ ﺗﻪﺭﺟﯩــﻤﻪ ﻣﻪﺷــﻐﯘﻻﺗﯩﻨﻰ ﺋﯧﻠﯩــﭗ ﺑــﺎﺭﻏﯘﭼﻰ ﺑﻮﻟــﺴﺎ »ﻛــﻮﺩ-ﺗﻪﺭﺟﯩﻤــﺎﻥ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ.
ﻣـــﯘﯞﻩﻗﻘﻪﺕ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩـــﺴﻰ ،delegateﺧﻪﻧﺰﯗﭼﯩـــﺴﻰ 委托ﺑﻮﻟـــﯘﭖ ،ﯞﻩﻛﯩـــﻞ ،ﮬـــﺎﯞﺍﻟﻪ، ﻣﯘﯞﻩﻗﻘﻪﺕ ﺩﯦﮕﻪﻥ ﻣﻪﻧﯩﻠﻪﺭﺩﻩ .ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺪﺍ delegateﺧﺎﺳﻠﯩﻘﻰ ﺑﯧﺮﯨﻠﮕﻪﻥ ﺗﯩﭙﻼﺭ ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﺑﺎﺷﻘﺎ ﻛﻮﺩﻻﺭﻧﯩـﯔ ﺋﺎﺩﺭﯦـﺴﯩﻨﻰ ﺳـﺎﻗﻼﻳﺪﯨﻐﺎﻥ ﯞﻩﻛﯩـﻞ ﺗﯩـﭙﻼﺭﺩﯗﺭ .ﺷـﯘﯕﺎ »ﻣـﯘﯞﻩﻗﻘﻪﺕ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ. ﺧﯘﻟــﻖ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩــﺴﻰ behaviorﺑﻮﻟــﯘﭖ ،ﭘﺮﻭﮔﺮﺍﻣﻤﯩــﺪﺍ ﻣﻪﻟــﯘﻡ ﻛﻮﺩﻧﯩــﯔ ﺋﯩﺠــﺮﺍ ﺑﻮﻟــﯘﺵ ﺋﺎﻻﮬﯩــﺪﯨﻠﯧﻜﯩﻨﻰ ﯞﻩ ﺧﯩــﺰﻣﻪﺕ ﭘﯩﺮﯨﻨــﺴﯩﭙﯩﻨﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ .ﺩﯦــﻤﻪﻙ ﺋــﯘ ﺷــﯘ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﻨﯩــﯔ ﺧﯘﻟﻘﻰ.
8
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺧﺎﺱ ﺳﯚﺯ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ ،Key Word :ﺧﻪﻧﺰﯗﭼﯩﺴﻰ 关键词,保留词 :ﺑﻮﻟـﯘﭖ ،ﮬﻪﺭﺑﯩـﺮ ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﺗﯩﻠﯩﺪﺍ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﻻﺭ ﺗﻪﺭﯨﭙﯩﺪﯨﻦ ﺋﯩﺸﻠﯩﺘﯩﺸﻜﻪ ﺑﻮﻟﻤﺎﻳﺪﯨﻐﺎﻥ ﺑﯩﺮ ﻗﯩﺴﯩﻢ ﺳـﯚﺯﻟﻪﺭﻧﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ .ﻣﻪﺳــﯩﻠﻪﻥ C# ،ﺗﯩﻠﯩــﺪﺍ … int, float, delegate, public, staticﻗﺎﺗــﺎﺭﻟﯩﻖ ﺳﯚﺯﻟﻪﺭ ﺧﺎﺱ ﺳﯚﺯﻟﻪﺭﮔﻪ ﺗﻪﯞﻩ ﺑﻮﻟﯘﭖ ﺋﯘﻻﺭﻧﻰ ﺋﯚﺯﮔﻪﺭﮔﯜﭼﻰ ﻣﯩﻘﺪﺍﺭﻻﺭﻧﯩﯔ ﺋﯩﺴﯩﻤﻰ ﺳﯜﭘﯩﺘﯩﺪﻩ ﻗﻮﻟﻠﯩﻨﯩﺸﯩﻤﯩﺰﻏﺎ ﻳﻮﻝ ﻗﻮﻳﯘﻟﻤﺎﻳـﺪﯗ .ﺑﯘﻧـﺪﺍﻕ ﺳـﯚﺯﻟﻪﺭ ﮬﻪﺭﺑﯩـﺮ ﺗﯩﻠﻨﯩـﯔ ﺋـﯚﺯﻯ ﺋﯜﭼـﯜﻥ ﺧـﺎﺱ ﺑﻮﻟﻐﺎﻧﻠﯩﻘﻰ ﺋﯜﭼﯜﻥ ﺋﯘﻻﺭ »ﺧﺎﺱ ﺳـﯚﺯ« ﺩﻩﭖ ﺋﯧﻠﯩﻨـﺪﻯ .ﻟـﯧﻜﯩﻦ ﺋـﺎﭼﻘﯘﭼﻠﯘﻕ ﺳـﯚﺯ ،ﻳﻪﻧـﻰ 关键词ﺧﺎﺱ ﺳﯚﺯﺩﯨﻦ ﭘﻪﺭﻗﻠﯩﻨﯩﺪﯨﻐﺎﻥ ﺑﻮﻟﯘﭖ ،ﺋﯘﻧﯩﯔ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺶ ﺩﺍﺋﯩﺮﯨﺴﻰ ﻛﻪﯕﺮﻩﻙ .ﺋـﯘ ﻣﻪﻟﯘﻡ ﻧﻪﺗﯩﺠﯩﮕﻪ ﺋﯧﺮﯨﺸﯩﺶ ﺋﯜﭼﯜﻥ ﺗﻪﻣﯩﻨﻠﯩﮕﻪﻥ ﺋﺎﭼﻘﯘﭼﻠﯘﻕ ﺋﯘﭼﯘﺭﻧﻰ ﻛﯚﺭﺳﯩﺘﯩﺪﯗ. ﺑﯩﻨﻮﺭﻣـــﺎﻟﻠﯩﻖ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩـــﺴﻰ ،Exceprion :ﺧﻪﻧﺰﯗﭼﯩـــﺴﻰ 异常 :ﺑﻮﻟـــﯘﭖ ،ﺗﺎﺳـــﺎﺩﺩﯨﺒﯩﻠﯩﻖ، ﺑﯩﻨﻮﺭﻣــﺎﻟﻠﯩﻖ ﺩﯦــﮕﻪﻥ ﻣﻪﻧﯩﻠﻪﺭﻧــﻰ ﺑﯧﺮﯨــﺪﯗ .ﭘﺮﻭﮔﺮﺍﻣﻤﯩــﺪﺍ ﺋــﯘ ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ ﺋﯩﺠــﺮﺍ ﺟﻪﺭﻳﺎﻧﯩــﺪﺍ ﺧﺎﺗــﺎﻟﯩﻖ ﻛﯚﺭﯛﻟﺴﻪ ﮬﺎﺳﯩﻞ ﺑﻮﻟﯩـﺪﯨﻐﺎﻥ ﺧﺎﺗـﺎﻟﯩﻖ ﺗﯩﭙﯩﻨﯩـﯔ ﺋﻮﺭﺗـﺎﻕ ﻧـﺎﻣﻰ .ﻣﻪﺳـﯩﻠﻪﻥ int i=1/0; ،ﺑـﯘ ﺟـﯜﻣﻠﻪ IDEﺗﻪﺭﯨﭙﯩــﺪﯨﻦ ﺧﺎﺗــﺎﻟﯩﻖ ﻳــﻮﻕ ﺩﻩﭖ ﻗﺎﺭﯨﻠﯩــﺪﯗ .ﺋﻪﻣﻤــﺎ ﮬﻪﺭﻗﺎﻧــﺪﺍﻕ ﺳــﺎﻧﻨﻰ 0ﮔﻪ ﺑﯚﻟــﺴﻪ ﻣﻪﻧﯩــﺴﯩﺰ ﺑﻮﻟﯩــــــﺪﯨﻐﺎﻧﻠﯩﻘﻰ ﺋﯜﭼــــــﯜﻥ ﭘﺮﻭﮔﺮﺍﻣﻤــــــﺎ ﺋﯩﺠــــــﺮﺍ ﺑﻮﻟــــــﯘﭖ ﻣﯘﺷــــــﯘ ﺟــــــﯜﻣﻠﯩﮕﻪ ﻛﻪﻟﮕﻪﻧــــــﺪﻩ DevidedByZeroExceptionﺗﯩﭙﻠﯩــﻖ ﺧﺎﺗــﺎﻟﯩﻖ ﺋــﻮﺑﻴﯧﻜﯩﺘﻰ ﮬﺎﺳــﯩﻞ ﻗﯩﻠﯩــﺪﯗ .ﺑــﯘ ﺧﯩــﻞ ﮬﺎﺩﯨــﺴﻪ »ﺑﯩﻨﻮﺭﻣــﺎﻟﻠﯩﻖ« ﺩﻩﭖ ﺋﯧﻠﯩﻨــﺪﻯ .ﻣﻪﺳــﯩﻠﻪﻥ ،ﺑﺎﻳــﺎﻣﻘﻰ ﺟﻪﺭﻳﺎﻧــﺪﺍ DevidedByZeroException ﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨﻠﯩﺪﯗ. ﺗﯩﺰﻣﺎ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ ،Sequance :ﺧﻪﻧﺰﯗﭼﯩﺴﻰ 串 :ﺑﻮﻟﯘﭖ ،ﺑﯩﺮﻗﺎﻧﭽﻪ ﺋﯧﻠﯧﻤﯧﻨﺘﻼﺭﻧﯩـﯔ ﺭﻩﺗﻠﯩـﻚ ﻗﺎﺗــﺎﺭﯨﻨﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ .ﭘﺮﻭﮔﺮﺍﻣﻤﯩــﺪﺍ Sequance ،ﺋﯩﭽﯩــﺪﯨﻜﻰ ﺋﯧﻠﯧﻤﯧﻨــﺘﻼﺭ ﺗﻪﺭﺗﯩﭙﻠﯩــﻚ ﺗﯩﺰﯨﻠﻐــﺎﻥ ﺑﻮﻟﯘﭖ ،ﺋﯘﻻﺭﻏﺎ ﻧﯚﻟﺪﯨﻦ ﺑﺎﺷﻼﻧﻐﺎﻥ ﺗﻪﺭﺗﯩﭗ ﻧﻮﻣﯘﺭﻯ ﻗﻮﻳﯘﻟﻐﺎﻥ ﺑﻮﻟﯩـﺪﯗ .ﺋـﯘﻻﺭ ﺗﻪﺭﺗﯩﭙﻠﯩـﻚ ﺗﯩﺰﯨﻠﻐـﺎﻥ ﺋﺎﻻﮬﯩﺪﯨﻠﯩﻜﯩﻰ ﻛﯚﺯﺩﻩ ﺗﯘﺗﯘﭖ ﺋﯘﻻﺭﻧﻰ »ﺗﻮﭘﻼﻡ« ﺩﻩﭖ ﺋﯧﻠﯩﺸﻨﯩﯔ ﺋﻮﺭﻧﯩﻐـﺎ »ﺗﯩﺰﻣـﺎ« ﺩﻩﭖ ﺋﯧﻠﯩﻨـﺪﻯ. ﮔﻪﺭﭼﻪ (集合)Collectionﻣﯘ ﺋﯧﻠﯧﻤﯧﻨﺘﻼﺭﻧﯩﯔ ﺗـﻮﭘﻰ ﺑﻮﻟـﺴﯩﻤﯘ ،ﺋـﯘ ﺳـﻪﻝ ﺋﺎﺑـﺴﺘﺮﺍﻛﺘﺮﺍﻕ ﺑﻮﻟـﯘﭖ، ﺋﯘﻧﯩــﯔ ﺋﯩﭽﯩــﺪﯨﻜﻰ ﺋﯧﻠﯧﻤﯧﻨــﺘﻼﺭ ﺗﻪﺭﺗﯩﭙﻠﯩــﻚ ﺑﻮﻟﯘﺷــﯩﻤﯘ ﻣــﯘﻣﻜﯩﻦ ،ﺗﻪﺭﺗﯩﭙــﺴﺰ ﺑﻮﻟﯘﺷــﯩﻤﯘ ﻣــﯘﻣﻜﯩﻦ. ﻣﻪﺳﯩﻠﻪﻥ Hashtable ،ﺩﯨﻜﻰ ﺋﯧﻠﯧﻤﯧﻨﺘﻼﺭﻧﻰ ﺗﻪﺭﺗﯩﭗ ﻧﻮﻣﯘﺭﻯ ﺑﯩﻠﻪﻥ ﺯﯨﻴﺎﺭﻩﺕ ﻗﯩﻠﻐﯩﻠﻰ ﺑﻮﻟﻤﺎﻳﺪﯗ. ﺋﻪﺯﺍ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩـــﺴﻰ ،Item :ﺧﻪﻧﺰﯗﭼﯩـــﺴﻰ 项 :ﺑﻮﻟـــﯘﭖ ،ﻣﻪﻟـــﯘﻡ ﺗﯩﺰﻣـــﺎ ﺋﯩﭽﯩـــﺪﯨﻜﻰ ﺑﯩـــﺮ ﺩﺍﻧﻪ ﺋﯧﻠﯧﻤﻨﯧﺘﻨــﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ .ﻣﻪﺳــﯩﻠﻪﻥ } int[] sanlar = new int[]{1,2,3,4ﺩﻩﭖ ﺋﯧﻨﯩﻘﻼﻧﺴﺎ1,2,3 ،ﯞﻩ 4ﻟﻪﺭ sanlarﻧﯩﯔ ﺋﻪﺯﺍﻟﯩﺮﯨﺪﯗﺭ. ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ ،Query :ﺧﻪﻧﺰﯗﭼﯩﺴﻰ 查询 :ﺑﻮﻟﯘﭖ ،ﺋﯩﺰﺩﻩﺵ ،ﺳﯜﺭﯛﺷـﺘﻪ ﻗﯩﻠﯩـﺶ ﺩﯦـــﮕﻪﻥ ﻣﻪﻧﯩـــﻠﻪﺭﺩﻩ .ﻛﻮﻣﭙﻴـــﯘﺗﯧﺮ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﭽﯩﻠﯩﻘـــﻰ ﺳﺎﮬﻪﺳـــﯩﺪﻩ ﺑـــﯘ ﺋﺎﺗـــﺎﻟﻐﯘ ﺳـــﺎﻧﺪﺍﻥ)(数据库 ﻣﻪﺷﻐﯘﻻﺗﯩﺪﺍ ﺋﯩﻨﺘﺎﻳﯩﻦ ﻛﯚﭖ ﺋﯩـﺸﻠﯩﺘﯩﻠﯩﺪﯗ .ﺑﻮﻟﯘﭘﻤـﯘ ﺑـﺎﺭﻟﯩﻖ Sqlﺟـﯜﻣﻠﯩﻠﯩﺮﻯ ﺑﯩـﺮﺩﻩﻙ Queryﺩﻩﭖ ﺋﺎﺗﯩﻠﯩﺪﯗ .ﺑﯘ ﺧﯩـﻞ ﺋﺎﻻﮬﯩـﺪﯨﻠﯩﻜﻨﻰ ﺋﯘﻳﻐـﯘﺭ ﺗﯩﻠﯩـﺪﺍ »ﺳﯜﺭﯛﺷـﺘﯜﺭﮔﯜﭼﻰ«» ،ﺋﯩـﺰﺩﻩﺵ ﺟﯜﻣﻠﯩـﺴﻰ«، »ﺋﯩﺰﺩﯨﮕــﯜﭼﻰ« ﺩﯦﮕﻪﻧــﺪﻩﻛﻼﺭ ﺑﯩــﻠﻪﻥ ﺋﯩﭙــﺎﺩﯨﻠﻪﺵ ﻣــﯘﻣﻜﯩﻦ .ﻟــﯧﻜﯩﻦ Queryﺟﻪﺭﻳﺎﻧﯩﻨﯩــﯔ ﺋــﯘﻧﻰ ﺋﯩــﺸﻠﻪﺗﻜﯜﭼﻰ )ﺳﯜﺭﯛﺷــﺘﯜﺭﮔﯜﭼﻰ( ﺩﯨــﻦ ﭘﻪﺭﻗﻠﯩﻨﯩــﺪﯨﻐﺎﻥ ﻣﯘﺳــﺘﻪﻗﯩﻞ ﺟﻪﺭﻳــﺎﻥ ﺑﻮﻟﻐــﺎﻧﻠﯩﻘﻰ ﻛــﯚﺯﺩﻩ ﺗﯘﺗﯘﻟــﯘﭖ »ﺳﯜﺭﯛﺷــﺘﯜﺭ« ﺳــﯚﺯﯨﮕﻪ »ﯛﻙ« ﺳــﯚﺯ ﻳﺎﺳــﯩﻐﯘﭼﻰ ﻗﻮﺷﯘﻣﭽﯩــﺴﯩﻨﻰ ﻗﻮﺷــﯘﺵ ﺋــﺎﺭﻗﯩﻠﯩﻖ »ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ.
9
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﯩﺘـﺎﺏ ﻣﻪﺯﻣﯘﻧﯩـﺪﺍ SQL ،ﺳﯜﺭﯛﺷـﺘﯜﺭﯛﻛﻰ ) LINQ ،(SQL Queryﺳﯜﺭﯛﺷـﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨـﺴﻰ ) LINQ Expression
،(Queryﺳﯜﺭﯛﺷــــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨــــﺴﻰ)Expression
(Queryﻗﺎﺗــــﺎﺭﻟﯩﻖ
»ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ« ﻧﻰ ﺋﯚﺯ ﺋﯩﭽﯩﮕﻪ ﺋﺎﻟﻐﺎﻥ ﺋﺎﺗﺎﻟﻐﯘﻻﺭﻧﻰ ﺋﯘﭼﺮﯨﺘﯩﭗ ﺗﯘﺭﯨﺴﯩﺰ .ﺋﯘﻻﺭﻏـﺎ ﺋـﺎﻳﺮﯨﻢ ﺋﯩﺰﺍﮬـﺎﺕ ﺑﯧﺮﯨﻠﻤﯩﺪﻯ.
ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺋﺎﺗﺎﻟﻐﯘﻻﺭﻧﯩﯔ ﺗﻪﺭﺟﯩﻤﯩﺴﯩﻼ ﺑﯧﺮﯨﻠﺪﻯ ﺋﯘﻳﻐﯘﺭﭼﯩﺴﻰ
ﺗﯘﺭﻏﯘﻥ ﻗﻪﯞﻩﺕ
ﺧﻪﻧﺰﯗﭼﯩﺴﻰ
ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ
Static Layer
静态层
Predicate
谓语
ﻗﺎﺗﺘﯩﻖ ﺗﯩﭙﻠﯩﻖ ﺗﯩﻞ
Strongly Typed Language
强类型语言
ﺗﯩﭗ ﻛﻪﻟﺘﯜﺭﯛﻟﻤﯩﺴﻰ
Type Inference
类型推导
ﻛﯚﺭﺳﻪﺗﻤﻪ
ﺋﻪﻣﻪﻟﯩﻴﻪﺷﺘﯜﺭﯛﺵ ﭼﺎﺭﻻﺵ ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﺗﯩﭗ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭗ
Projection Enumerate Value Type
值类型
Reference Type
引用类型
ﺋﻪﺳﻜﻪﺭﺗﯩﺶ :ﻳﯘﻗﯩﺮﯨﻘﻰ ﺋﺎﺗﺎﻟﻐﯘﻻﺭ ﺑﯩﺮﺩﻩﻙ ﺑﯩﺮ ﻗﯩﺴﯩﻢ ﻛﻪﺳﯩﭙﺪﺍﺷﻼﺭ ﺑﯩـﻠﻪﻥ ﭘﯩﻜﯩﺮﻟﯩـﺸﯩﺶ ﺋﺎﺳﺎﺳـﯩﺪﺍ ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﯩﻨﻐﺎﻥ ،ﻣﯘﺷﯘ ﻛﯩﺘﺎﺑﺘﯩﻦ ﺑﺎﺷﻘﺎ ﮬﻪﺭﻗﺎﻧﺪﺍﻕ ﻣﺎﺗﯧﺮﻳﺎﻟﻼﺭﺩﯨﻜﻰ ﺋﻮﺧﺸﺎﺵ ﺋﺎﺗﺎﻟﻐﯘﻻﺭﻏﺎ ﺋﺎﺳﺎﺱ ﺑﻮﻻﻟﻤﺎﻳــﺪﯗ .ﮬﻪﻡ ﻣﻪﺯﻛــﯘﺭ ﺗﻪﺭﺟﯩﻤﯩــﻠﻪﺭ ﺳــﻪﯞﻩﺑﻠﯩﻚ ﻛﯧﻠﯩــﭗ ﭼﯩﻘﻘــﺎﻥ ﮬﻪﺭﻗﺎﻧــﺪﺍﻕ ﻣﻪﺳــﺌﯘﻟﯩﻴﻪﺗﻨﻰ ﺋﯜﺳﺘﯩﻤﯩﺰﮔﻪ ﺋﺎﻟﻤﺎﻳﻤﯩﺰ.
10
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﯩﻜﻜﯩﻨﭽﻰ ﺑﺎﺏ C#ﺗﯩﻠﯩﻨﯩﯔ ﺧﯘﺳﯘﺳﯩﻴﻪﺗﻠﯩﺮﻯ ﺗﯩﻠﻐﺎ ﺑﺎﻏﻼﻧﻐﺎﻥ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ) (LINQﻧﻰ ﺋﯩـﺸﻠﯩﺘﯩﺶ ﺋﯜﭼـﯜﻥ C#3.0ﺩﯨﻜـﻰ ﺑـﺎﺭﻟﯩﻖ ﻳﯧﯖﯩﻠﯩﻘﻼﺭﻧـﻰ ﺋﯩﮕﯩﻠﻪﺵ ﮬﺎﺟﻪﺗﺴﯩﺰ .ﻣﻪﺳﯩﻠﻪﻥ ،ﮬﯧﭽﺒﯩﺮ ﻳﯧﯖﯩﻠﯩﻖ »ﺗﯩﻠﻼﺭﻏﺎ ﺋﻮﺭﺗﺎﻕ ﺋﯩﺠﺮﺍ ﺳﯘﭘﯩـﺴﻰ«) (CLRﻧﯩـﯔ
ﺋﯚﺯﮔﯩﺮﯨﺸﯩﻨﻰ ﺗﻪﻟﻪﭖ ﻗﯩﻠﻤﺎﻳﺪﯗ LINQ .ﺑﻮﻟﺴﺎ ﻳﯧﯖﻰ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﺎﻧﻼﺭ) C# 3.0ﻳﺎﻛﻰ Microsoft (Visual Basic 9.0ﻏﺎ ﺑﯧﻘﯩﻨﯩﺪﯨﻐﺎﻥ ﺑﻮﻟﯘﭖ ،ﺑﯘ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤـﺎﻧﻼﺭ Microsoft .NET2.0ﺩﯨﻤـﯘ ﻧﻮﺭﻣﺎﻝ ﺋﯩﺸﻠﻪﻳﺪﯨﻐﺎﻥ ﺋﯚﺗﻜﯜﻧﭽﻰ ﻛﻮﺩ ﮬﺎﺳﯩﻞ ﻗﯩﻼﻻﻳﺪﯗ. ﻗﺎﻧـﺪﺍﻗﻼ ﺑﻮﻟﻤﯩـﺴﯘﻥ ،ﺑـﯘ ﺑﺎﺑﺘـﺎ C#ﺗﯩﻠﯩﻨﯩـﯔ ) C# 1.0ﺩﯨـﻦ C# 3.0ﻏﯩـﭽﻪ( ﺧﯘﺳﯘﺳـﯩﻴﻪﺗﻠﯩﺮﯨﻨﻰ ﻗﯩﺴﻘﯩﭽﻪ ﺗﻮﻧﯘﺷﺘﯘﺭﯗﭖ ﺋﯚﺗﯜﺵ ﻣﯘﯞﺍﭘﯩﻖ ﺑﯩﻠﯩﻨﺪﻯ .ﺷﯘﻧﺪﯨﻼ C#ﺗﯩﻠﻰ ﺋﺎﺳﺎﺳﯩﯖﯩﺰﻧﯩﯔ ﺋﺎﺟﯩﺰ ﺑﻮﻟﯘﺷﻰ ﺳﻪﯞﻩﺑﻠﯩﻚ LINQﺑﯩﻠﯩﻤﻠﯩﺮﯨﻨﻰ ﺋﺎﯕﻘﯩﺮﺍﻟﻤﺎﺳﻠﯩﻘﯩﯖﯩﺰﻧﯩﯔ ﺋﺎﻟﺪﯨﻨﻰ ﺋـﺎﻟﻐﯩﻠﻰ ﺑﻮﻟﯘﺷـﻰ ﻣـﯘﻣﻜﯩﻦ .ﺋﻪﮔﻪﺭ ﻣﻪﺯﻛﯘﺭ ﺑﺎﺑﻨﻰ ﺋﺎﺗﻼﭖ ﺋﯚﺗﯜﭖ ﻛﻪﺗـﺴﯩﯖﯩﺰ LINQ ،ﮔﺮﺍﻣﻤﺎﺗﯧﻜﯩـﺴﯩﻨﯩﯔ ﮬﻪﻗﯩﻘـﻰ ﻣـﺎﮬﯩﻴﯩﺘﯩﻨﻰ ﺑﯩﻠﮕﯩﯖﯩـﺰ ﻛﻪﻟﮕﻪﻧﺪﻩ ﻗﺎﻳﺘﺎ ﻛﯚﺭﯛﭖ ﺑﺎﻗﺎﺭﺳﯩﺰ.
C# 2.0ﮔﻪ ﻗﺎﻳﺘﺎ ﻧﻪﺯﻩﺭ C# 2.0ﺩﻩ ﺋﻪﺳﻠﯩﺪﯨﻜﻰ C#ﺗﯩﻠـﻰ ﺋﺎﺳﺎﺳـﯩﺪﺍ ﻛـﯚﭖ ﺋﯩﻠﮕﯩﺮﻟﻪﺷـﻠﻪﺭ ﺑﻮﻟـﺪﻯ .ﻣﻪﺳﯩﻠﻪﻥ،ﻛﯚﭘﻤﺎﺳـﻠﯩﻖ ﺋﯘﻗﯘﻣﯩﻨﯩﯔ ﻗﻮﺷﯘﻟﯘﺷﻰ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﻻﺭﻧﻰ ﺑﯩﺮﺩﯨﻦ ﺋﺎﺭﺗﯘﻕ ﺗﯩﭗ ﭘـﺎﺭﺍﻣﯧﺘﺮﯨﻨﻰ ﺋـﯚﺯ ﺋﯩﭽﯩـﮕﻪ ﺋﺎﻟﻐـﺎﻥ ﺗـﯜﺭ ﯞﻩ ﻣﯧﺘـﻮﺩﻻﺭﻧﻰ ﻳﯧــﺰﯨﺶ ﺋﯩﻤﻜـﺎﻧﯩﻴﯩﺘﯩﮕﻪ ﺋﯩــﮕﻪ ﻗﯩﻠـﺪﻯ .ﺋﻪﻣﻪﻟﯩﻴﻪﺗـﺘﻪ ،ﻛﯚﭘﻤـﺎﺱ ﺑﻮﻟــﺴﺎ LINQﻧﯩــﯔ ﺗﺎﻳﺎﻧﭽﯩﺴﻰ. ﻣﻪﺯﻛﯘﺭ ﭘﺎﺭﺍﮔﺮﺍﻓﺘﺎ» ،ﻛﯚﭘﻤﺎﺳـﻠﯩﻖ«» ،ﻧﺎﻣـﺴﯩﺰ ﻣﯧﺘـﻮﺩ«) C# 3.0ﺩﯨﻜـﻰ lambdaﺋﯩﭙﺎﺩﯨﻠﯩﺮﯨﻨﯩـﯔ ﺋﺎﺳﺎﺳﻰ ( yield ،ﺧﺎﺱ ﺳﯚﺯﻯ ﯞﻩ IEnumerableﺋﯧﻐﯩﺰﻯ ﻗﺎﺗﺎﺭﻟﯩﻖ LINQﺋﯜﭼﯜﻥ ﺋﯩﻨﺘﺎﻳﯩﻦ ﻣـﯘﮬﯩﻢ ﺑﻮﻟﻐﺎﻥ C# 2.0ﻧﯩﯔ ﺧﯘﺳﯘﺳﯩﻴﻪﺗﻠﯩﺮﻯ ﺗﻮﻧﯘﺷﺘﯘﺭﯗﻟﯩﺪﻯ LINQ .ﻧﻰ ﮬﻪﻗﯩﻘﯩـﻲ ﭼﯜﺷـﯜﻧﯜﺵ ﺋﯜﭼـﯜﻥ ﺑﯘ ﺋﯘﻗﯘﻣﻼﺭﻧﻰ ﺑﯩﻠﯩﺶ ﺯﯙﺭﯛﺭﺩﯗﺭ.
ﻛﯚﭘﻤﺎﺳﻠﯩﻖ ﻧﯘﺭﻏﯘﻥ ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﺗﯩﻠﻠﯩﺮﯨﺪﺍ ﺋﯚﺯﮔﻪﺭﮔﯜﭼﻰ ﻣﯩﻘﺪﺍﺭ ﯞﻩ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﻰ ﻛﻮﻧﺘﺮﻭﻝ ﻗﯩﻠﯩﺶ ﺋﯜﭼـﯜﻥ ﺋﯧﻨﯩـﻖ ﺗﯩﭗ ﯞﻩ ﺗﯩﭙﻼﺭﻧﻰ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺷﻘﺎ ﻛﻪﺳﻜﯩﻦ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻗﺎﺋﯩﺪﯨﻠﯩﺮﻯ ﺑﯧﻜﯩـﺘﯩﻠﮕﻪﻥ .ﺋﻮﻣﯘﻣﻼﺷـﺘﯘﺭﯗﺵ ﻧﯘﺧﺘﯩـــﺴﯩﺪﯨﻦ ﺋﯧﻴﺘﻘﺎﻧـــﺪﺍ ،ﻗـــﺎﺗﺘﯩﻖ ﺗﯩﭙﻠﯩـــﻖ ﺗﯩﻠـــﻼﺭﺩﺍ ﻳﯧﺰﯨﻠﻐـــﺎﻥ ﻛـــﻮﺩﻻﺭﺩﺍ ﺑﻪﺯﻯ ﻧﻮﻗـــﺴﺎﻧﻼﺭﻧﯩﯔ ﺳﺎﻗﻼﻧﻐﺎﻧﻠﯩﻘﯩﻨﻰ ﺑﺎﻳﻘﺎﻳﻤﯩﺰ .ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻛﻮﺩﻗﺎ ﻗﺎﺭﺍﻳﻠﻰ:
int Min( int a, int b ) { if (a < b) return a; else return b; } ﻳﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩﺗﯩﻜﻰ Minﻣﯧﺘﻮﺩﻯ ﭘﻪﻗﻪﺕ ﺗﯩﭙﻰ intﺑﻮﻟﻐﺎﻥ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻻﺭﻏﯩﻼ ﻣﻪﺷﻐﯘﻻﺕ ﺑﯩﺠﯩﺮﻩﻟﻪﻳﺪﯗ. ﺋﻪﮔﻪﺭ ﺋﯘﻧﻰ ﺑﺎﺷﻘﺎ ﺗﯩﭙﻠﯩﻖ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻻﺭﻏﺎ ﻗﻮﻟﻼﻧﻤﺎﻗﭽﻰ ﺑﻮﻟﺴﺎﻕ ،ﭼﻮﻗﯘﻡ ﺷﯘ ﺗﯩﭙﻘﺎ ﺧﺎﺱ ﻣﯧﺘﻮﺩ
11
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
float Min( float a, float b ) { if (a < b) return a; else return b; } objectﺗﯩﭙــﻰ ﺑــﺎﺭﻟﯩﻖ ﺗﯩﭙﻼﺭﻧﯩــﯔ ﺋﺎﺗﯩــﺴﻰ ﺑﻮﻟﻐﺎﭼﻘــﺎ ،ﺑــﺎﻻ ﺗﯩﭙﻼﺭﻧــﻰ ﺋﯘﻧﯩﯖﻐــﺎ ﺋﺎﻟﻤﺎﺷــﺘﯘﺭﻏﯩﻠﻰ ﯞﻩ ﺋﻪﺳﻠﯩﮕﻪ ﻗﺎﻳﺘﯘﺭﻏﯩﻠﻰ ﺑﻮﻟﯩﺪﯗ ،ﺷﯘﯕﺎ objectﺗﯩﭙﯩﻨﻰ ﺋﻮﺭﺗﺎﻕ ﺗﯩﭗ ﻗﯩﻠﯩﭗ ﺋﯩﺸﻠﯩﺘﯩﺸﻜﻪ ﺋﺎﺩﻩﺗﻠﻪﻧﮕﻪﻥ ﭘﺮﻭﮔﺮﺍﻣﻤﯧﺮﻻﺭ ﺑﻪﻟﻜﯩﻢ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛـﻮﺩ ﻳﯧﺰﯨـﭗ ﻳـﯘﻗﯩﺮﯨﻘﻰ ﺋـﺎﯞﺍﺭﯨﭽﯩﻠﯩﻘﺘﯩﻦ ﻗﯘﺗﯘﻟﻤـﺎﻗﭽﻰ ﺑﻮﻟﯘﺷـﻰ ﻣﯘﻣﻜﯩﻦ:
object Min( object a, object b ) { if (a < b) return a; else return b; } ﺗﻮﻟﯩﻤــﯘ ﺋﻪﭘــﺴﯘﺱ ،ﺋﻮﻣﯘﻣﻼﺷــﻘﺎﻥ objectﺗﯩﭙﯩﻐــﺎ ﻧﯩــﺴﺒﻪﺗﻪﻥ »ﺩﻯ ﻛﯩﭽﯩــﻚ«)<( ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﺶ ﺋﯜﻧﯜﻣﺴﯩﺰﺩﯗﺭ .ﺷﯘﯕﺎ ﻳﻪﻧﯩﻼ ﺋﻮﺭﺗﺎﻕ ﺋﯧﻐﯩﺰﻧﻰ ﺋﯩﺸﺘﻠﯩﺘﯩﺸﻜﻪ ﺗﻮﻏﺮﺍ ﻛﯧﻠﯩﺪﯗ:
IComparable Min( IComparable a, IComparable b ) { if (a.CompareTo( b ) < 0) return a; else return b; } ﮔﻪﺭﭼﻪ ﻣﻪﺳﯩﻠﯩﻨﻰ ﺩﻩﻣﺎﻟﻠﯩﻖ ﮬﻪﻝ ﻗﯩﻠﻐﺎﻥ ﺑﻮﻟﺴﺎﻗﻤﯘ ،ﻟﯧﻜﯩﻦ ﭼﻮﯓ ﭘﯧﺸﻜﻪﻟﺪﯨﻦ ﺑﯩﺮﻧﻰ ﺗﯧﺮﯨﺪﯗﻕMin : ﻓﯘﻧﻜﯩﺴﯩﻴﯩﺴﻰ ﺋﯩﺠﺮﺍ ﺟﻪﺭﻳﺎﻧﯩﺪﺍ ﺋﯚﺗﻜﯜﻧﭽﻰ ﺗﯩﭗ ﮬﺎﺳﯩﻞ ﻗﯩﻠﯩﭗ ﻗﻮﻳﺪﻯ .ﻳﻪﻧﻰ ،ﻣﻪﺳﯩﻠﻪﻥ Min ،ﻧﻰ ﺋﯩﺸﻠﻪﺗﻜﯜﭼﯩﻨﯩﯔ ﺋﯘﻧﯩﯖﻐﺎ ﺋﯩﻜﻜﻰ ﺩﺍﻧﻪ intﺗﯩﭙﻠﯩﻖ ﭘﯜﺗﯜﻥ ﺳﺎﻥ ﻳﻮﻟﻠﯩﺸﻰ intﺩﯨﻦ IComparableﻏـﺎ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﯩﻨﻰ ﻛﻪﻟﺘﯜﺭﯛﭖ ﭼﯩﻘﯩﺮﯨـﺪﯗ ،ﻟـﯧﻜﯩﻦ ﺑـﯘ ﺟﻪﺭﻳـﺎﻥ ﺋﯧـﻨﯩﻘﻼ ﺋـﺎﺭﺗﯘﻗﺘﯩﻦ-ﺋـﺎﺭﺗﯘﻕ CPUﭼﯩﻘﯩﻤﻰ ﺗﻪﻟﻪﭖ ﻗﯩﻠﯩﺪﯗ .ﮬﻪﺗﺘﺎ ﺑﻪﺯﯨﺪﻩ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ) (Exceptionﭼﯩﻘﯩﺮﯨﺸﯩﻤﯘ ﻣﯘﻣﻜﯩﻦ.
int a = 5, b = 10; int c = (int) Min( a, b ); C# 2.0ﺩﺍ ﺑﯘ ﻣﻪﺳﯩﻠﻪ ﻛﯚﭘﻤﺎﺳﻠﯩﻖ ﺋﺎﺭﻗﯩﻠﯩﻖ ﮬﻪﻝ ﻗﯩﻠﯩﻨﺪﻯ .ﻛﯚﭘﻤﺎﺳﻠﯩﻘﻨﯩﯔ ﺋﺎﺳﺎﺳـﻰ ﭘﯩﺮﯨﻨـﺴﯩﭙﻰ ﺷﯘﻛﻰ C# ،ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﺎﻧﯩﻨﯩﯔ ﺗﯩﭗ ﺭﻩﺗﻠﻪﺵ ﺧﯩﺰﻣﯩﺘﻰ ﮬﺎﺯﯨﺮ-ﺟﺎﯞﺍﺏ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﺎﻧﻐﺎ ﺋﯚﺗﻜﯜﺯﯛﭖ ﺑﯧﺮﯨﻠﺪﻯ .ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ Minﻓﯘﻧﻜﯩﺴﯩﻴﯩﺴﯩﻨﯩﯔ ﻛﯚﭘﻤﺎﺱ ﻧﯘﺳﺨﯩﺴﻰ:
T Min
( T a, T b ) where T : IComparable { if (a.CompareTo( b ) < 0) return a; else return b; }
12
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﻪﺳﻜﻪﺭﺗﯩﺶ :ﮬﺎﺯﯨﺮ-ﺟﺎﯞﺍﺏ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﺎﻥ) (Jitterﺩﯦﮕﯩﻨﯩﻤﯩﺰ .NETﺋﯩﺠﺮﺍ ﺳﯘﭘﯩـﺴﯩﻨﯩﯔ ﺑﯩـﺮ ﻗﯩﺴﻤﻰ ﺑﻮﻟﯘﭖ ،ﺋـﯘ ﺋﯚﺗﻜـﯜﻧﭽﻪ ﻛـﻮﺩ ILﻧـﻰ ﻣﺎﺷـﯩﻨﺎ ﻛﻮﺩﯨﻐـﺎ ﺋﺎﻳﻼﻧﺪﯗﺭﯨـﺪﯗ .NET .ﻣﻪﻧـﺒﻪ ﻛـﻮﺩﯨﻨﻰ ﻛــﻮﺩ-ﺗﻪﺭﺟﯩــﻤﻪ ﻗﯩﻠﻐﯩﻨﯩﯖﯩــﺰﺩﺍ ،ﺋﯩﺠــﺮﺍ ﺑﻮﻻﻻﻳــﺪﯨﻐﺎﻥ ﯞﻩ ILﻛــﻮﺩﯨﻨﻰ ﺋــﯚﺯ ﺋﯩﭽﯩــﮕﻪ ﺋﺎﻟﻐــﺎﻥ ﮬﺎﺳــﯩﻠﻪ ﻳﺎﺳــﺎﻳﺪﯗ .ﺑــﯘ ﮬﺎﺳــﯩﻠﻪ ﭘﻪﻗﻪﺕ ﺗــﯘﻧﺠﻰ ﻗﯧــﺘﯩﻢ ﺋﯩﺠــﺮﺍ ﺑﻮﻟﻐﺎﻧــﺪﯨﻼ ﮬــﺎﺯﯨﺮ-ﺟــﺎﯞﺍﺏ ﻛــﻮﺩ-ﺗﻪﺭﺟﯩﻤــﺎﻥ ﺗﻪﺭﯨﭙﯩﺪﯨﻦ ﻣﺎﺷﯩﻨﺎ ﻛﻮﺩﯨﻐﺎ ﺋﺎﻳﻼﻧﺪﯗﺭﯗﻟﯩﺪﯗ. ﺗﯩﭗ ﺭﻩﺗﻠﻪﺵ ﯞﻩﺯﯨﭙﯩﺴﯩﻨﻰ ﮬﺎﺯﯨﺮ ﺟﺎﯞﺍﺏ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﺎﻧﻐـﺎ ﺗﺎﭘـﺸﯘﺭﯗﺵ ﻳﺎﺧـﺸﻰ ﻗـﺎﺭﺍﺭ .ﭼـﯜﻧﻜﻰ :ﺋـﯘ ﺋﻮﺧﺸﺎﺵ ﻛﻮﺩﻧﯩﯔ ﺋﻮﺧﺸﯩﻤﯩﻐﺎﻥ ﻧﯘﺳﺨﯩﻠﯩﺮﯨﻨﻰ ﮬﺎﺳﯩﻞ ﻗﯩﻼﻻﻳﺪﯗ ،ﺷﯘﯕﺎ ﺋﻮﺧـﺸﯩﻤﯩﻐﺎﻥ ﻧﯘﺳـﺨﯩﺪﯨﻜﻰ ﻛﻮﺩﻧﻰ ﺋﻮﺧـﺸﯩﻤﯩﻐﺎﻥ ﺗﯩﭙﻼﺭﻏـﺎ ﺋﯩـﺸﻠﻪﺗﻜﯩﻠﻰ ﺑﻮﻟﯩـﺪﯗ .ﺑـﯘ ﺋﯘﺳـﯘﻝ ﻣـﺎﻛﺮﻭﻟﯘﻕ ﻛﯧﯖﻪﻳﺘﯩـﺸﻜﻪ ﺋﻮﺧـﺸﺎﭖ ﻗﺎﻟﯩــﺪﯗ .ﺋﻮﺧــﺸﯩﻤﺎﻳﺪﯨﻐﺎﻥ ﻳﯧــﺮﻯ ،ﺑــﯘ ﺋﯘﺳــﯘﻟﻐﺎ ﻛﻮﺩﻧﯩــﯔ ﺷــﯩﺪﺩﻩﺕ ﺑﯩــﻠﻪﻥ ﻛﯚﭘﯩﻴﯩــﺸﯩﻨﯩﯔ ﺋﺎﻟــﺪﯨﻨﻰ ﺋﯧﻠﯩﺶ ﺋﯜﭼﯜﻥ ﻳﺎﺧﺸﯩﻠﯩﻨﯩﺶ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﻐﺎﻥ .ﻳﻪﻧﻰ ،ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭙﻠﯩﻖ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻧﻰ ﻛﯚﭘﻤﺎﺱ ﺗﯩﭙﻰ ﺋﻮﺭﻧﯩــﺪﺍ ﺋﯩــﺸﻠﯩﺘﯩﺪﯨﻐﺎﻥ ﻛﯚﭘﻤــﺎﺱ ﻣﯧﺘــﻮﺩﻻﺭ ﺋﯜﭼــﯜﻥ ﺑﯩــﺮﻻ ﻧﯘﺳــﺨﯩﺪﺍ ILﻛــﻮﺩﻯ ﮬﺎﺳــﯩﻞ ﻗﯩﻠﯩــﭗ ﻗﻮﻳﯩﺪﯨﻐﺎﻥ ﺋﻪﮬﯟﺍﻝ ﻣﻪﯞﺟﯘﺕ ﺋﯩﺪﻯ. ﻛﯚﭖ ﻣﺎﺳﻠﯩﻖ ﺋﺎﺭﻗﯩﻠﯩﻖ
int a = 5, b = 10; int c = (int) Min( a, b ); ﻧﯩﯔ ﺋﻮﺭﻧﯩﻐﺎ
int a = 5, b = 10; int c = Min( a, b ); ﺩﻩﻙ ﻳﺎﺯﺍﻻﻳﻤﯩﺰ. ﺋﻪﻣــﺪﻯ ،ﺑــﯘﺭﯗﻥ ﺗﯩــﭗ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺷــﻘﺎ ﺳــﻪﺭﭖ ﻗﯩﻠﯩــﭗ ﻳــﯜﺭﮔﻪﻥ CPUﭼﯩﻘﯩﻤﻠﯩﺮﯨﻤﯩــﺰ ﺗﯧﺠﯩﻠﯩــﭗ، ﭘﺮﻭﮔﺮﺍﻣﻤﯩﻤﯩــﺰ ﺗﯧﺨﯩﻤــﯘ ﺗﯧــﺰ ﺋﯩﺠــﺮﺍ ﺑﻮﻟﯩــﺪﯨﻐﺎﻥ ﺑﻮﻟﺪﯨــﺪﻩ ....ﭼــﯜﻧﻜﻰ ﺑــﯘﻳﻪﺭﺩﻩ ﮬﯧﭽﻘﺎﻧــﺪﺍﻕ ﺗﯩــﭗ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﻰ ﻳﯜﺯ ﺑﻪﺭﻣﻪﻳﺪﯗ .ﺋﯘﻧﯩﯔ ﺋﯜﺳﺘﯩﮕﻪ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤـﺎﻥ ﺑﯧـﺮﯨﻠﮕﻪﻥ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻧﯩـﯔ ﻗﯩﻤﻤﯩﺘﯩﮕﻪ ﺋﺎﺳﺎﺳﻪﻥ ﻛﯚﭘﻤﺎﺱ ﺗﯩﭗ Tﻧﯩﯔ ﺋﯧﻨﯩﻖ ﺗﯩﭙﯩﻨﻰ ﭘﻪﺭﻩﺯ ﻗﯩﻼﻻﻳﺪﯗ)ﺗﯩﭗ ﻛﻪﻟﺘﯜﺭﯛﻟﻤﯩـﺴﻰ ﺩﻩﭖ ﺋﺎﺗﯩﻠﯩﺪﯗ( .ﺷﯘﯕﺎ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩﻧﻰ ﺗﯧﺨﯩﻤﯘ ﺋﺎﺩﺩﯨﻴﻼﺷﺘﯘﺭﯗﭖ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻛﻤﯘ ﻳﺎﺯﺍﻻﻳﻤﯩﺰ:
int a = 5, b = 10; int c = Min( a, b ); ﺗﯩﭗ ﻛﻪﻟﺘﯜﺭﯛﻟﻤﯩﺴﻰ :ﺗﯩﭗ ﻛﻪﻟﺘﯜﺭﯛﻟﻤﯩﺴﻰ ﺋﯩﻨﺘﺎﻳﯩﻦ ﻣﯘﮬﯩﻢ ﺋﯩﻘﺘﯩﺪﺍﺭ ﺑﻮﻟﯘﭖ ،ﺋﯘ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤـﺎﻧﻨﻰ ﺗﯩﭙﻘﺎ ﺋﺎﻻﻗﯩﺪﺍﺭ ﺗﻪﭘﺴﯩﻠﯩﻲ ﺋﯩﺸﻼﺭﻏﺎ ﺑﯘﻳﺮﯗﭖ ،ﺳﯩﺰﻧﻰ ﺗﯧﺨﯩﻤﯘ ﺋﺎﺑﺴﺘﺮﺍﻛﺖ ﻛﻮﺩ ﻳﯧﺰﯨﺶ ﺋﯩﻤﻜـﺎﻧﯩﻴﯩﺘﯩﮕﻪ ﺋﯩﮕﻪ ﻗﯩﻠﯩﺪﯗ. ﻛﯚﭘﻤﺎﺳــﻠﯩﻘﺘﯩﻦ ﭘﺎﻳــﺪﯨﻠﯩﻨﯩﭗ ﻛﯚﭘﻤــﺎﺱ ﻣﯧﺘــﻮﺩ ﺋﯧــﻨﯩﻘﻠﯩﻐﯩﻠﯩﻼ ﺑﻮﻟــﯘﭖ ﻗﺎﻟﻤــﺎﻱ ،ﻳﻪﻧﻪ ﻛﯚﭘﻤــﺎﺱ ﺗــﯜﺭ، ﺋﯧﻐﯩﺰﻻﺭﻧﯩﻤــﯘ ﺋﯧﻨﯩﻘﻠﯩﻐﯩﻠــﻰ ﺑﻮﻟﯩــﺪﯗ .ﻛﯚﭘﻤﺎﺳــﻠﯩﻖ ﺋﯜﺳــﺘﯩﺪﻩ ﺗــﻮﺧﺘﯩﻠﯩﺶ ﺑــﯘ ﻛﯩﺘﺎﺑﻨﯩــﯔ ﺋﺎﺳﺎﺳــﻠﯩﻖ ﻣﻪﻗــﺴﯩﺘﻰ ﺑﻮﻟﻤﯩﻐﺎﭼﻘــﺎ ﺗﻪﭘــﺴﯩﻠﯩﻲ ﺗﻮﺧﺘﺎﻟﻤــﺎﻱ .ﻟــﯧﻜﯩﻦ ،ﺷــﯘﻧﻰ ﻳﻪﻧﻪ ﺩﯦﮕﯩــﻢ ﻛﻪﻟــﺪﻯ :ﻛﯚﭘﻤﺎﺳــﻠﯩﻘﻨﻰ ﭼﯜﺷﻪﻧﻤﻪﻱ ﺗﯘﺭﯗﭖ LINQﻛﯚﺭﺳﯩﯖﯩﺰ ﺋﯚﺯﯨﯖﯩﺰﻧﻰ ﺭﺍﮬﻪﺕ ﮬﯧﺲ ﻗﯩﻼﻟﻤﺎﻳﺴﯩﺰ.
13
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻣﯘﯞﻩﻗﻘﻪﺗﻠﻪﺭ ﻣﯘﯞﻩﻗﻘﻪﺕ ﺩﯦﮕﯩﻨﯩﻤﯩـﺰ ﺑﯩـﺮ ﻳـﺎﻛﻰ ﺑﯩـﺮﺩﯨﻦ ﺋـﺎﺭﺗﯘﻕ ﻣﯧﺘﻮﺩﻧﯩـﯔ ﻗﺎﭘﻼﻧﻤـﺎ ﺗﯜﺭﯨـﺪﯨﻦ ﺋﯩﺒـﺎﺭﻩﺕ .ﺋﯩﭽﻜـﻰ ﻗﯩﺴﯩﻤﺪﺍ ،ﺑﯩـﺮ ﺩﺍﻧﻪ ﻣـﯘﯞﻩﻗﻘﻪﺗﺘﻪ ﻣﯘﺷـﯘ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﻗﺎﭘﻠﯩﻐـﺎﻥ ﻣﯧﺘﻮﺩﻻﺭﻏـﺎ ﻗﺎﺭﯨﺘﯩﻠﻐـﺎﻥ ﺋﯩـﺴﺘﯧﺮﯦﻠﻜﯩﻼﺭ ﺗﯩﺰﻣﯩﺴﻰ ﺳﺎﻗﻠﯩﻨﯩﺪﯗ .ﮬﻪﺭ ﺑﯩﺮ ﺋﯩﺴﺘﺮﯦﻠﻜﺎ ﺋﯚﺯﻯ ﺗﻮﻏﯘﺭﻻﻧﻐﺎﻥ ﻣﯧﺘﻮﺩﻧﻰ ﺋـﯚﺯ ﺋﯩﭽﯩـﮕﻪ ﺋﺎﻟﻐـﺎﻥ ﺗﯜﺭﯨﻨﯩـﯔ ﭼﺎﻗﯩﺮﯨﻠﻤﯩﺴﯩﻐﺎ ﻣﺎﺱ ﻛﯧﻠﯩﺪﯗ. ﮬﻪﺭﺑﯩﺮ ﻣﯘﯞﻩﻗﻘﻪﺕ ﺑﯩﺮ-ﻗﺎﻧﭽﻪ ﻣﯧﺘـﻮﺩﻧﻰ ﻗﺎﭘﻠﯩﻴﺎﻻﻳـﺪﯗ .ﻟـﯧﻜﯩﻦ ﺑـﯘ ﭘﺎﺭﺍﮔﺮﺍﻓﺘـﺎ ﭘﻪﻗﻪﺕ ﺑﯩـﺮﻻ ﻣﯧﺘـﻮﺩﻧﻰ ﻗﺎﭘﯩﻠﯩﻐﺎﻥ ﻣﯘﯞﻩﻗﻘﻪﺗﻠﻪﺭ ﻛﯚﭘﺮﻩﻙ ﻛﯚﯕـﯜﻝ ﺑﯚﻟﯩﻨﯩـﺪﯗ .ﺋﺎﺑـﺴﺘﺮﺍﻛﺘﺮﺍﻕ ﻧﯘﺧﺘﯩـﺪﯨﻦ ﺋﯧﻠﯩـﭗ ﺋﯧﻴﺘـﺴﺎﻕ ،ﺑـﯘ ﺧﯩﻠــﺪﯨﻜﻰ ﻣــﯘﯞﻩﻗﻘﻪﺗﻠﻪﺭﻧﻰ »ﻛــﻮﺩ ﻗــﺎﭘﭽﯘﻗﻰ« ﻏــﺎ ﺋﻮﺧــﺸﯩﺘﯩﺶ ﻣــﯘﻣﻜﯩﻦ .ﺑــﯘ ﻗــﺎﭘﭽﯘﻗﺘﯩﻜﻰ ﻛــﻮﺩﻧﻰ ﺋﯚﺯﮔﻪﺭﺗﻜﯩﻠﻰ ﺑﻮﻟﻤﺎﻳﺪﯗ .ﻟﯧﻜﯩﻦ ﺋﯘ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺩﻩﺳـﺘﯩﻠﯩﺮﯨﮕﻪ ﺋﻪﮔﯩـﺸﯩﭗ ﻳﯚﺗﻜﯩﻠﻪﻟﻪﻳـﺪﯗ ﮬﻪﻣـﺪﻩ ﺗـﺎﻛﻰ ﺋــﯘﻧﻰ ﺋﯩــﺸﻠﯩﺘﯩﺶ ﺋﯧﮫﺘﯩﻴــﺎﺟﻰ ﻗﺎﻟﻤﯩﻐﺎﻧﻐــﺎ ﻗﻪﺩﻩﺭ ﻣﻪﯞﺟــﯘﺕ ﺑﻮﻟــﯘﭖ ﺗﯘﺭﺍﻻﻳــﺪﯗ .ﺋﯘﻧﯩﯖــﺪﯨﻦ ﺑﺎﺷــﻘﺎ، ﻣﯘﯞﻩﻗﻘﻪﺕ ﻳﻪﻧﻪ ،ﺋﯚﺯﻯ ﻗﺎﭘﻠﯩﻐـﺎﻥ ﻣﯧﺘـﻮﺩﻧﻰ ﺋـﯚﺯ ﺋﯩﭽﯩـﮕﻪ ﺋﺎﻟﻐـﺎﻥ ﺗـﯜﺭﻧﻰ ﮬـﯧﭻ ﺑﻮﻟﻤﯩﻐﺎﻧـﺪﺍ ﺋﯚﺯﯨﻨﯩـﯔ ﺋﯚﻣﺮﻯ ﺑﯩﻠﻪﻥ ﺗﻪﯓ ﻳﺎﺷﯩﻐﯘﺯﺍﻻﻳﺪﯗ. ﻧﺎﻣﺴﯩﺰ ﻣﯧﺘﻮﺩ ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﻣﯘﯞﻩﻗﻘﻪﺗﻨﯩﯔ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﺴﯩﻐﺎ ﺋﺎﺳﺎﺳﻪﻥ ﺋﯚﺯﮔﻪﺭﺗﯩﻠﯩﭗ ﻗﯘﺭﯗﻟﻐﺎﻥ .ﺋﯘﻧﯩﯖﻐـﺎ ﺋﺎﺋﯩﺖ ﻣﻪﺯﻣﯘﻧﻼﺭ ﻛﯧﻴﯩﻨﻜﻰ ﭘﺎﺭﺍﮔﺮﺍﻓﺘـﺎ ﺳـﯚﺯﻟﯩﻨﯩﺪﯗ .ﻣـﯘﯞﻩﻗﻘﻪﺗﺘﯩﻦ ﺑﯩﺮﻧـﻰ ﺋﯧـﻨﯩﻘﻼﺵ ﺋﻪﻣﻪﻟﯩﻴﻪﺗـﺘﻪ ﺷـﯘ ﻣﯘﯞﻩﻗﻘﻪﺗﻨﯩﯔ ﺋﯚﺯﯨﻨﻰ ﻗﯘﺭﯨﺪﯨﻐﺎﻥ ﺗﯩﭙﺘﯩﻦ ﺑﯩﺮﻧﻰ ﺋﯧـﻨﯩﻘﻼﺵ ﺑﯩـﻠﻪﻥ ﺑـﺎﺭﺍﯞﻩﺭ .ﻣـﯘﯞﻩﻗﻘﻪﺕ ﺋﯧﻨﯩﻘﻠﯩﻐﺎﻧـﺪﺍ ﭼﻮﻗـــﯘﻡ ﺋﯘﻧﯩـــﯔ ﻣﯧﺘـــﻮﺩ ﺋﻪﻧﺪﯨﺰﯨـــﺴﯩﻨﻰ ﺗﻮﻟـــﯘﻕ ﺗﻪﻣﯩﻨﻠﯩـــﺸﻰ ﻛﯧـــﺮﻩﻙ .ﻛـــﻮﺩ 2.1ﺩﺍ ﺋـــﯜﭺ ﺧﯩـــﻞ ﺋﻮﺧﺸﯩﻤﺎﻳﺪﯨﻐﺎﻥ ﻣﯘﯞﻩﻗﻘﻪﺗﻨﯩﯔ ﺋﯧﻨﯩﻘﻠﯩﻤﯩﺴﻰ ﺑﯧﺮﯨﻠﺪﻯ .ﺋﯘﻻﺭ ﺋﯚﺯﻟﯩﺮﻯ ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ ﺋﻪﻧﺪﯨﺰﯨﺪﯨﻜﻰ ﻣﯧﺘﻮﺩﻻﺭﻧﻰ ﻗﺎﭘﻠﯩﻴﺎﻻﻳﺪﯗ. ﻛﻮﺩ 2.1
delegate void SimpleDelegate(); delegate int ReturnValueDelegate(); delegate void TwoParamsDelegate( string name, int age ); ﻣﯘﯞﻩﻗﻘﻪﺕ ﺑﯘﺭﯗﻧﻘﻰ Cﺗﯩﻠﯩﺪﯨﻜﻰ ﻓﯘﻧﻜﯩﺴﯩﻴﻪ ﺋﯩﺴﺘﺮﯦﻠﻜﯩﺴﯩﻐﺎ ﻗﺎﺭﯨﻐﺎﻧﺪﺍ ﺗﯧﺨﯩﻤﯘ ﻗﯧﻠﯩﭙﻼﺷﻘﺎﻥ ،ﺗﯧﺨﯩﻤﯘ ﺑﯩﺨﻪﺗﻪﺭ C# 1.x .ﺩﻩ ﺋﺎﺷﻜﺎﺭﻩ ﻳﻮﺳﯘﻧﺪﺍ ﺋﻮﺑﻴﯧﻜﯩﺖ ﻗﯘﺭﯗﺵ ﺋﯘﺳـﯘﻟﻰ ﺋـﺎﺭﻗﯩﻠﯩﻘﻼ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﻗـﯘﺭﻏﯩﻠﻰ ﺑﻮﻻﺗﺘﻰ .ﻣﻪﺳﯩﻠﻪﻥ ﻛﻮﺩ 2.2ﺩﺍ ﻛﯚﺭﺳﯩﺘﯩﻠﮕﻪﻧﺪﻩﻙ: ﻛﻮﺩ 2.2
public class DemoDelegate { void MethodA() { … } int MethodB() { … } void MethodC( string x, int y ) { … } void CreateInstance() { SimpleDelegate a = new SimpleDelegate( MethodA ); ReturnValueDelegate b = new ReturnValueDelegate ( MethodB );
14
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
TwoParamsDelegate c = new TwoParamsDelegate( MethodC ); } } C# 1.xﺩﯨﻜﻰ ﻣﯘﯞﻩﻗﻘﻪﺕ ﺋﯧﻨﯩﻘﻼﺵ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﺴﯩﺪﺍ ﻧﻮﻗﺴﺎﻥ ﺑﺎﺭﻟﯩﻘﯩﻨﻰ ﺑﺎﻳﻘﯩـﺪﯨﯖﯩﺰﻣﯘ؟ .ﻗﺎﺋﯩﺪﯨـﺴﻰ ﺑﻮﻳﯩﭽﻪ ﻧﯩـﺸﺎﻥ ﻣﯧﺘﻮﺩﯨﻨﯩـﯔ ﺋﻪﻧﺪﯨﺰﯨـﺴﻰ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﺋﻪﻧﺪﯨﺰﯨـﺴﻰ ﺑﯩـﻠﻪﻥ ﺑﯩـﺮﺩﻩﻙ ﺑﻮﻟﯘﺷـﻰ ﻛﯧـﺮﻩﻙ. ﺋﯘﻧــﺪﺍﻕ ﺑﻮﻟﻤﯩﻐﺎﻧــﺪﺍ ﻛﻮﻣﭙﯩﻼﻳــﺪﯨﻦ ﺋﯚﺗﻤﻪﻳــﺪﯗ .ﺷــﯘﻧﺪﺍﻕ ﺗﯘﺭﯗﻗﻠــﯘﻕ ﻳﻪﻧﻪ ﻧــﯧﻤﻪ ﺋﯜﭼــﯜﻥ newﺧــﺎﺱ ﺳﯚﺯﯨﻨﻰ ﺋﯩـﺸﻠﯩﺘﯩﻤﯩﺰ ،ﺋـﯘﻧﻰ ﺋﯩـﺸﻠﯩﺘﯩﺶ ﺋﯧـﻨﯩﻘﻼ ﺑﯩـﺰﺩﯨﻦ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﺋﯩـﺴﻤﯩﻨﻰ ﺑﯩﻠﯩـﺸﯩﻤﯩﺰﻧﻰ ﺗﻪﻟﻪﭖ ﻗﯩﻠﯩــﺪﯗ .ﺋﻪﻣﻪﻟﯩﻴﻪﺗــﺘﻪ ﻣــﯘﯞﻩﻗﻘﻪﺕ ﺗﯩﭙﯩﻨــﻰ ﻛﻮﺩﻧﯩــﯔ ﺑــﺎﺵ-ﺋــﺎﺧﯩﺮﯨﻨﻰ ﺗﻪﮬﻠﯩــﻞ ﻗﯩﻠﯩــﺶ ﺋــﺎﺭﻗﯩﻠﯩﻘﻤﯘ ﻛﻪﻟﺘﯜﺭﯛﭖ ﭼﯩﻘﯩﺮﯨﯟﺍﻟﻐﯩﻠﻰ ﺑﻮﻟﯩﺪﯗ)ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﺎﻥ ﺷﯘﻧﺪﺍﻕ ﻗﯩﻠﯩﺸﻰ ﻛﯧﺮﻩﻙ ﺋﯩﺪﻯ(. C# 2.0ﺩﻩ ﺑﯘ ﻣﻪﺳﯩﻠﻪ ﺑﺎﻳﻘﯩﻠﯩﭗ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﺴﻰ ﺗﯧﺨﯩﻤﯘ ﺋﺎﺩﺩﯨﻴﻼﺷﺘﯘﺭﯗﻟﺪﻯ .ﺋﺎﻟﺪﯨﻨﻘﻰ ﻣﯩﺴﺎﻝ ﻛﻮﺩﺩﺍ ﻗﯘﺭﻏـﺎﻥ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﺋــﻮﺑﻴﯧﻜﯩﺘﯩﻨﻰ ﺋﻪﻣـﺪﻯ newﺧـﺎﺱ ﺳــﯚﺯﯨﻨﻰ ﺋﯩـﺸﻠﻪﺗﻤﻪﻱ ﺗﯘﺭﯗﭘﻤـﯘ ﻗﯘﺭﺍﻻﻳــﺪﯨﻐﺎﻥ ﺑﻮﻟﺪﯗﻕ .ﭘﻪﻗﻪﺕ ﻣﯧﺘﻮﺩ ﻧـﺎﻣﯩﻨﻰ ﻳـﻮﻟﻼﭖ ﺑﻪﺭﺳـﻪﻛﻼ ﺑﻮﻟﯩـﺪﯗ .ﻛـﻮﺩ-ﺗﻪﺭﺟﯩﻤـﺎﻥ ﻣﯧﺘـﻮﺩ ﺋﻪﻧﺪﯨﺰﯨـﺴﯩﮕﻪ ﺋﺎﺳﺎﺳﻪﻥ ﻣﯘﯞﻩﻗﻘﻪﺕ ﺗﯩﭙﯩﻨﻰ ﻛﻪﻟﺘﯜﺭﯛﭖ ﭼﯩﻘﯩﺮﯨﭗ new ،ﺧـﺎﺱ ﺳـﯚﺯﯨﻨﻰ ﻛـﻮﺩ-ﺗﻪﺭﺟﯩـﻤﻪ ﺟﻪﺭﻳﺎﻧﯩـﺪﺍ ﺋﺎﭘﺘﻮﻣﺎﺗﯩﻚ ﻗﻮﺷﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ ،ﻛﻮﺩ 2.3ﺩﯨﻜﻰ C# 2.0ﻛﻮﺩﻯ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﯩﻨﯩﺶ ﺋﺎﺭﻗﯩﻠﯩﻖ ﮬﺎﺳــﯩﻞ ﺑﻮﻟﻐــﺎﻥ ILﻛــﻮﺩﻯ C# 1.x ،ﻧﯩــﯔ ﻣﯩــﺴﺎﻝ ﻛﻮﺩﯨــﺪﺍ ﮬﺎﺳــﯩﻞ ﻗﯩﻠﯩﻨﻐﯩﻨــﻰ ﺑﯩــﻠﻪﻥ ﺋﻮﭘﻤــﯘ- ﺋﻮﺧﺸﺎﺵ. ﻛﻮﺩ 2.3
public class DemoDelegate { void MethodA() { … } int MethodB() { … } void MethodC( string x, int y ) { … } void CreateInstance() { SimpleDelegate a = MethodA; ReturnValueDelegate b = MethodB; TwoParamsDelegate c = MethodC; // … } // … } ﮬﻪﺗﺘﺎ ﻛﯚﭘﻤﺎﺱ ﻣﯘﯞﻩﻗﻘﻪﺗﻤﯘ ﺋﯧﻨﯩﻘﻠﯩﻴﺎﻻﻳـﺴﯩﺰ .ﺑـﯘ ،ﻛﯚﭘﻤـﺎﺱ ﺗﯜﺭﻧﯩـﯔ ﺋﯩﭽﯩـﺪﻩ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﺋﯧﻨﯩﻘﻼﺷـﺘﺎ ﺑﻪﻛﻼ ﺋﻪﺳﻘﺎﺗﯩﺪﯗ .ﺋﯘﻧﯩﯔ ﺋﯜﺳﺘﯩﮕﻪ ﻛﯚﭘﻤﺎﺱ ﻣﯘﯞﻩﻗﻘﻪﺕ LINQﺩﺍ ﺋﯩﻨﺘﺎﻳﯩﻦ ﻣﯘﮬﯩﻢ ﺋﻮﺭﯗﻥ ﺗﯘﺗﯩﺪﯗ. ﻣﻪﯞﺟــﯘﺕ ﻣﯧﺘﻮﺩﻧﯩــﯔ ﺋﯩﭽﯩــﮕﻪ ﮬﻪﺭﻛﻪﺗﭽــﺎﻥ ﮬــﺎﻟﻪﺗﺘﻪ ﻛــﻮﺩ ﻗﯩــﺴﺘﯘﺭﯗﺵ ﺑﻮﻟــﺴﺎ ﻣﯘﯞﻩﻗﻘﻪﺗﻨﯩــﯔ ﺋﻪﯓ ﺋﻮﻣﯘﻣﻼﺷﻼﺷﻘﺎﻥ ﻗﻮﻟﻠﯩﻨﯩﺸﯩﺪﯗﺭ .ﻛﻮﺩ 2.4ﺩﺍ Repeat10Timesﺑﻮﻟﺴﺎ ﺋﯚﺯﮔﻪﺭﺗﻜﯩﻤﯩﺰ ﻳﻮﻕ ﻣﯧﺘﻮﺩ:
15
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﻮﺩ 2.4
public class Writer { public string Text; public int Counter; public void Dump() { Console.WriteLine( Text ); Counter++; } } public class DemoDelegate { void Repeat10Times( SimpleDelegate someWork ) { for (int i = 0; i < 10; i++) someWork(); } void Run1() { Writer writer = new Writer(); writer.Text = "C# chapter"; this.Repeat10Times( writer.Dump ); Console.WriteLine( writer.Counter ); } // … } ﻧــﯚﯞﻩﺗﺘﻪ SimpleDlegateﺗﯩﭙﻠﯩــﻖ ﭼــﺎﻗﯩﺮﻏﯘ ﻣﻪﯞﺟــﯘﺕ) simpleWorkﺷــﯘ( ،ﺑﯩــﺮﺍﻕ ﺑﯩﺰﻧﯩــﯔ ﻣﻪﻗﺴﯩﺘﯩﻤﯩﺰ ﻗﯩﺴﺘﯘﺭﯗﻟﻐﺎﻥ ﻣﯧﺘﻮﺩﻗﺎ ﮬﻪﺭﭖ-ﺑﻪﻟﮕﻪ ﺗﯩﺰﻣﯩﺴﻰ ﻳﻮﻟﻼﭖ ﺑﯧـﺮﯨﺶ ﯞﻩ ﻗﯩـﺴﺘﯘﻟﻐﺎﻥ ﻣﯧﺘﻮﺩﻧﯩـﯔ ﻗــﺎﻧﭽﻪ ﻗﯧــﺘﯩﻢ ﺋﯩﺠــﺮﺍ ﺑﻮﻟﻐــﺎﻧﻠﯩﻘﯩﻨﻰ ﺳــﺎﻧﺎﺵ .ﺷــﯘﯕﺎ Dump ،ﻣﯧﺘــﻮﺩﻯ ﺋﯜﭼــﯜﻥ ﺋﯘﭼــﯘﺭ ﺗﻪﻣﯩــﻨﻠﻪﭖ ﺑﯧﺮﯨﺪﯨﻐﺎﻥ Writerﺗﯜﺭﯨﻨﻰ ﻗﯘﺭﯨﯟﺍﻟﺪﯗﻕ .ﺩﯦﻤﻪﻙ ،ﻛﻮﺩ ﻗﯩﺴﺘﯘﺭﯗﺵ ﺋﯜﭼﯜﻥ ﺋﯩﻜﻜـﻰ ﺗـﯜﺭ ﺋﯧﻨﯩﻘﻼﺷـﻘﺎ ﺗﻮﻏﺮﺍ ﻛﻪﻟﺪﻯ .ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺖ ﺑﯘ ﺧﯩـﻞ ﺋﯘﺳـﯘﻟﻨﻰ ﻧﺎﻣـﺴﯩﺰ ﻣﯧﺘـﻮﺩ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﺗﯧﺨﯩﻤـﯘ ﺋﺎﺩﺩﯨﻴﻼﺷـﺘﯘﺭﻏﯩﻠﻰ ﺑﻮﻟﯩﺪﯗ.
ﻧﺎﻣﺴﯩﺰ ﻣﯧﺘﻮﺩ ﺋﺎﻟﺪﯨﻨﻘﻰ ﺑﯚﻟﻪﻛﺘﻪ ،ﻣﯘﯞﻩﻗﻘﻪﺗﻨﯩﯔ ﺩﺍﺋﯩﻤﯩﻠﯩﻖ ﺋﯩﺸﻠﯩﺘﯩﺶ ﺋﯘﺳﯘﻟﻰ ﺋﯜﺳـﺘﯩﺪﻩ ﺗﻮﺧﺘﺎﻟـﺪﯗﻕ C# 2.0 .ﺩﻩ ﻧﺎﻣﺴﯩﺰ ﻣﯧﺘﻮﺩﻻﺭﻧﻰ ﻗﻮﻟﻠﯩﻨﯩﺶ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻛـﻮﺩ 2.4ﺩﯨﻜﯩـﺪﻩﻙ ﻛـﻮﺩﻻﺭﻧﻰ ﻳﯧﺰﯨـﺸﻨﯩﯔ ﺗﯧﺨﯩﻤـﯘ ﺋـﺎﺩﺩﯨﻲ ﻳﻮﻟﻠﯩﺮﻯ ﺗﻪﻣﯩﻨﻠﻪﻧﮕﻪﻥ .ﻣﻪﺳﯩﻠﻪﻥ:
16
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﻮﺩ 2.5
public class DemoDelegate { void Repeat10Times( SimpleDelegate someWork ) { for (int i = 0; i < 10; i++) someWork(); } void Run2() { int counter = 0; this.Repeat10Times( delegate { Console.WriteLine( "C# chapter" ); counter++; } ); Console.WriteLine( counter ); } // … } ﺑﯘ ﻛﻮﺩﺩﺍ Writerﺗـﯜﺭﯨﻨﻰ ﺋﯩﺸﻠﯩﺘﯩـﺸﻨﯩﯔ ﮬـﺎﺟﯩﺘﻰ ﺑﻮﻟﻤﯩـﺪﻯ .ﭼـﯜﻧﻜﻰ ﻛـﻮﺩ-ﺗﻪﺭﺟﯩﻤـﺎﻥ Writer ﺗﯜﺭﯨﻨﯩﯔ ﺭﻭﻟﯩﻨﻰ ﺋﯚﺗﻪﻳﺪﯨﻐﺎﻥ ﻧﺎﻣﺴﯩﺰ ﺗﯜﺭﻧﻰ ﻳﯘﺷﯘﺭﯗﻥ ﻗﯘﺭﯗﭖ ،ﺋﯩـﺸﻼﺭﻧﻰ ﺋـﯚﺯ ﻳﻮﻟﯩـﺪﺍ ﻣﺎﯕﻐﯘﺯﺍﻻﻳـﺪﯗ. ﺋﻪﻣﻪﻟﯩﻴﻪﺗــﺘﻪ ،ﺑﯩــﺰ Repeat10Timesﻧــﻰ ﭼــﺎﻗﯩﺮﯨﺶ ﺑﯩــﻠﻪﻥ ﺑﯩــﺮ ﯞﺍﻗﯩﺘﺘــﺎ ﻣﯧﺘــﻮﺩﺩﯨﻦ ﺑﯩﺮﻧــﻰ ﺋﯧﻨﯩﻘﻠﯩــﺪﯗﻕ .ﺋﯧﻨﯩﻘﻼﻧﻐــﺎﻥ ﻧﺎﻣــﺴﯩﺰ ﻣﯧﺘــﻮﺩ Repeat10Timesﻧﯩــﭗ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮﻯ someWorkﻗــﺎ ﻳﻮﻟﻠﯩﻨﯩﭗ ﻗﯩﺴﺘﯘﺭﯗﻟﻤﺎ ﺷﻪﻛﯩﻠﺪﻩ ﺋﯩﺠﺮﺍ ﺑﻮﻟﯩﯟﯦﺮﯨﺪﯗ ،ﺋﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ ﺋـﺎﻳﺮﯨﻢ ﺗـﯜﺭ ﺋﯧﻨﯩﻘﻼﺷـﻨﯩﯔ ﺋـﻮﺭﻧﻰ ﻗﺎﻟﻤﯩﺪﻯ .ﺑﯘ ﻳﻪﺭﺩﻩ ﺋﯧﻨﻘﻼﻧﻐﺎﻥ ﺋﺎﺷﯘ ﻧﺎﻣﻰ ﻳﻮﻕ ﻣﯧﺘﻮﺩ »ﻧﺎﻣﺴﯩﺰ ﻣﯧﺘﻮﺩ« ﺩﻩﭖ ﺋﺎﺗﯩﻠﯩﺪﯗ. ﻧﺎﻣﺴﯩﺰ ﻣﯧﺰﻭﺩ ﺋﯧﻨﯩﻘﻠﯩﻐﺎﻧﺪﺍ ﭼﻮﻗﯘﻡ delegateﺧﺎﺱ ﺳﯚﺯﯨﺪﯨﻦ ﺑﺎﺷﻠﯩﻨﯩﺸﻰ ﻛﯧﺮﻩﻙ. ﺷﯘﻧﯩﺴﻰ ﺋﯧﺴﯩﯖﯩﺰﺩﺍ ﺗﯘﺭﺳﯘﻥ :ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﻛﻮﺩ ﺋﯩﭽﯩﮕﻪ ﻛـﻮﺩ ﻗﯩـﺴﺘﯘﺭﻏﯩﻠﻰ ﺑﻮﻟﻤﺎﻳـﺪﯗ ،ﭘﻪﻗﻪﺕ ﻣﻪﻟـﯘﻡ ﻛﻮﺩﻗﺎ ﻗﺎﺭﯨﺘﯩﻠﻐﺎﻥ ﺋﯩﺴﺘﺮﯦﻠﻜﯩﻨﯩﻼ ﺑﺎﺷﻘﺎ ﻛﻮﺩ ﺑﯚﻟﯩﻜﻰ ﺋﯩﭽﯩﮕﻪ ﻗﯩﺴﺘﯘﺭﯗﺷﻘﺎ ﺑﻮﻟﯩﺪﯗ. ﺋﻪﮔﻪﺭ ﻧﺎﻣــﺴﯩﺰ ﻣﯧﺘــﻮﺩ ﻳﻮﻟﻼﻧﻤــﺎﻗﭽﻰ ﺑﻮﻟﻐــﺎﻥ ﺋﻮﺭﯗﻧــﺪﯨﻜﻰ ﻣــﯘﯞﻩﻗﻘﻪﺕ ﺗﯩﭙﻠﯩــﻖ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮ ﺗﻪﯞﻩ ﺑﻮﻟﻐــﺎﻥ ﻣــﯘﯞﻩﻗﻘﻪﺕ ﺗﯩﭙﯩﻨﯩــﯔ ﺋﻪﻧﺪﯨﺰﯨــﺴﯩﺪﻩ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮ ﺑﯧﻜﯩــﺘﯩﻠﮕﻪﻥ ﺑﻮﻟــﺴﺎ delegate ،ﺧــﺎﺱ ﺳــﯚﺯﯨﻨﯩﯔ ﺋﺎﺭﻗﯩﺴﯩﻐﺎ ﺗﯩﺮﻧﺎﻕ ﺋﯧﭽﯩﭗ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﯨﻠﯩﻖ ﺷﻪﻛﻠﯩﻨﻰ ﻗﻮﻟﻠﯩﻨﺸﯩﻘﺎ ﺑﻮﻟﯩﺪﯗ .ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻛـﻮﺩ 2.1ﺩﯨﻜـﻰ TwoParamsDlegateﺗﯩﭙﯩﻐﺎ ﻣﺎﺱ ﻧﺎﻣﺴﯩﺰ ﻣﯧﺘﻮﺩ ﺋﺎﺋﯩﺖ ﻣﯩﺴﺎﻝ ﺑﯧﺮﯨﻠﺪﻯ: ﻛﻮﺩ 2.6
public class DemoDelegate { void Repeat10Times( TwoParamsDelegate callback ) { for (int i = 0; i < 10; i++) callback( "Linq book", i ); }
17
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
void Run3() { Repeat10Times( delegate( string text, int age ) { Console.WriteLine( "{0} {1}", text, age ); } ); } // … }
Enumeratorsﯞﻩ Yield 1.x
C#ﺩﻩ ﭼـــﺎﺭﻻﺵ ﻣﻪﺷـــﻐﯘﻻﺗﯩﻨﻰ ﻗـــﻮﻟﻠﯩﺘﯩﺶ ﺋﯜﭼـــﯜﻥ ﺋﯩﻜﻜـــﻰ ﺩﺍﻧﻪ ﺋﯧﻐﯩـــﺰ ﺗﻪﻣﯩـــﻨﻠﻪﻧﮕﻪﻥ.
System.Collectionsﻧﺎﻡ ﺑﻮﺷﻠﯩﻘﯩﺪﺍ ﺋﯘﻻﺭﻧﯩﯔ ﺋﯧﻨﯩﻘﻠﯩﻤﯩﺴﻰ ﺑﯧﺮﯨﻠﮕﻪﻥ: ﻛﻮﺩ 2.7
public interface IEnumerator { bool MoveNext(); object Current { get; } void Reset(); } public interface IEnumerable { IEnumerator GetEnumerator(); } ﺩﯦــﻤﻪﻙ IEnumerable ،ﺋﯧﻐﯩﺰﯨﻨــﻰ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﻏﺎﻥ ﺋــﻮﺑﻴﯧﻜﯩﺘﻨﻰ IEnumeratorﺋﯧﻐﯩﺰﯨﻨــﻰ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﻏﺎﻥ ﺋﻮﺑﻴﯧﻜﯩــﺖ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﭼــﺎﺭﻟﯩﻐﯩﻠﻰ ﺑﻮﻟﯩــﺪﯗ .ﭼــﺎﺭﻻﺵ ﻣﻪﺷــﻐﯘﻻﺗﻰ MoveNext ﻣﯧﺘﻮﺩﯨﻨﻰ ﭼﺎﻗﯩﺮﯨﺶ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺗﺎﻛﻰ falseﻗﯩﻤﻤﻪﺕ ﻗﺎﻳﺘﯘﺭﯗﻟﻐﯩﭽﻪ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻼﻻﻳﺪﯗ. ﻛـــﻮﺩ 2.8ﺩﻩ ﻳـــﯘﻗﯩﺮﯨﻘﻰ ﺋﯘﺳـــﯘﻝ ﺋـــﺎﺭﻗﯩﻠﯩﻖ ﭼـــﺎﺭﻟﯩﻐﯩﻠﻰ ﺑﻮﻟﯩـــﺪﯨﻐﺎﻥ ﺗـــﯜﺭ ﺋﯧﻨﯩﻘﻼﻧـــﺪﻯ .ﻛـــﯚﺭﯛﭖ ﺗﯘﺭﻏﯩﻨﯩﯖﯩﺰﺩﻩﻙ CountdownEnumerator ،ﺗﯜﺭﻯ ﺋﯩﻨﺘﺎﻳﯩﻦ ﻣﯘﺭﻩﻛﻜﻪﭖ .ﺋﯘﻧﯩﯖـﺪﺍ ،ﭼﺎﺭﻟﯩﻐﯘﭼﯩﻨﯩـﯔ ﻗﺎﻳﺘﯘﺭﯨــــﺪﯨﻐﯩﻨﻰ ﺑﺎﺷــــﻘﺎ ﻧﻪﺭﺳــــﻪ ﺋﻪﻣﻪﺱ ﺑﻪﻟﻜــــﻰ Countdownﺗﯜﺭﯨــــﺪﻩ ﺋﯧﻨﯩﻘﻼﻧﻐــــﺎﻥ ﻣﯩﻘــــﺪﺍﺭ StartCountdownﺩﯨﻦ ﺑﺎﺷﻠﯩﻨﯩﭗ ﺑﯩﺮﺩﯨﻦ ﻛﯧﻤﯩﻴﯩﭗ ﺑﺎﺭﯨﺪﯨﻐﺎﻥ ﻗﯩﻤﻤﻪﺗﺪﯗﺭ. ﻛﻮﺩ 2.8
public class Countdown : IEnumerable { public int StartCountdown; public IEnumerator GetEnumerator() { return new CountdownEnumerator( this );
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
} } public class CountdownEnumerator : IEnumerator { private int _counter; private Countdown _countdown; public CountdownEnumerator( Countdown countdown ) { _countdown = countdown; Reset(); } public bool MoveNext() { if (_counter > 0) { _counter‐‐; return true; } else { return false; } } public void Reset() { _counter = _countdown.StartCountdown; } public object Current { get { return _counter; } } } . ﺋﯩﺸﻠﯩﺘﯩﻠﮕﻪﻧﺪﯨﻼ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﯩﺪﯗCountdonwEnumerator ﮬﻪﻗﯩﻘﯩﻲ ﭼﺎﺭﻻﺵ ﻣﻪﺷﻐﯘﻻﺗﻰ ﭘﻪﻗﻪﺕ : ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺸﯩﮕﻪ ﻗﺎﺭﺍﯓ،ﻣﻪﺳﯩﻠﻪﻥ 2.9 ﻛﻮﺩ
public class DemoEnumerator { public static void DemoCountdown() {
18
19
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
Countdown countdown = new Countdown(); countdown.StartCountdown = 5; IEnumerator i = countdown.GetEnumerator(); while (i.MoveNext()) { int n = (int) i.Current; Console.WriteLine( n ); } i.Reset(); while (i.MoveNext()) { int n = (int) i.Current; Console.WriteLine( "{0} BIS", n ); } } // … } GetEnumeratorﻣﯧﺘﻮﺩﯨﻨﻰ ﭼﺎﻗﯩﺮﯨﺶ ﺋﺎﺭﻗﯩﻠﯩﻖ ﭼﺎﺭﻟﯩﻐﯘﭼﻰ ﺋﻮﺑﻴﯧﻜﯩﺖ ﺗﻪﻣﯩﻨﻠﯩﻨﯩﺪﯗ .ﻛﻮﺩﺩﺍ ،ﺑﯩﺰ، Resetﻣﯧﺘﻮﺩﯨﻨﯩــﯔ ﺭﻭﻟﯩﻨــﻰ ﻧﺎﻣــﺎﻳﻪﻥ ﻗﯩﻠﯩــﺶ ﺋﯜﭼــﯜﻥ ﺋﯩﻜﻜــﻰ ﻗﯧــﺘﯩﻢ ﺋﺎﻳﻼﻧــﺪﯗﺭﯗﺵ) (loopﺋﯧﻠﯩــﭗ ﺑــﺎﺭﺩﯗﻕ Current .ﺧﺎﺳــﻠﯩﻘﻰ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﯧﺮﯨــﺸﻜﻪﻥ ﻗﯩﻤﻤﻪﺗﻨــﻰ ﭼﻮﻗــﯘﻡ intﻏــﺎ ﺋﺎﻳﻼﻧﺪﯗﺭﯗﺷــﯩﻤﯩﺰ ﻛﯧﺮﻩﻙ .ﭼﯜﻧﻜﻰ ﺑﯩﺰﻧﯩﯔ ﺋﯩﺸﻠﻪﺗﻜﯩﻨﯩﻤﯩﺰ ﭼﺎﺭﻻﺵ ﺋﯧﻐﯩﺰﻟﯩﺮﯨﻨﯩـﯔ ﻛﯚﭘﻤـﺎﺱ ﻧﯘﺳـﺨﯩﻠﯩﺮﻯ ﺑﻮﻟﻤﯩﻐﺎﭼﻘـﺎ، Currentﺩﯨﻦ ﻗﺎﻳﺘﯩﺪﯨﻐﯩﻨﻰ objectﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﯩﺪﯗ. ﺋﻪﺳــﻜﻪﺭﺗﯩﺶ C# 2.0 :ﺩﺍ ﻳﯧﯖﯩــﺪﯨﻦ ﻗﻮﺷــﯘﻟﻐﺎﻥ ﻛﯚﭘﻤــﺎﺱ ﺋﯘﻗــﯘﻣﯩﻨﻰ ﭼــﺎﺭﻻﺵ ﺋﯧﻐﯩﺰﻟﯩﺮﯨﻐﯩﻤــﯘ ﻗﻮﻟﻼﻧﻐﺎﻥ .ﻣﺎﺱ ﮬﺎﻟﺪﺍ System.Collections.Generic ،ﻧﺎﻡ ﺑﻮﺷﻠﯘﻗﯩﺪﺍ >IEnumerable IEnumerator
C#ﺩﯨـــﻦ ﺗﺎﺭﺗﯩـــﭗ foreach ،ﺟﯜﻣﻠﯩـــﺴﯩﻨﻰ ﺋﯩـــﺸﻠﯩﺘﯩﭗ ﭼـــﺎﺭﻻﺵ ﻣﻪﺷـــﻐﯘﻻﺗﯩﻨﻰ ﺗﯧﺨﯩﻤـــﯘ
ﺋﺎﺩﺩﯨﻴﻼﺷﺘﯘﺭﻏﯩﻠﻰ ﺑﻮﻟﺪﻯ .ﻛﻮﺩ 2.10ﻧﯩﯔ ﻧﻪﺗﯩﺠﯩﺴﻰ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﯩﺴﺎﻟﻨﯩﯖﻜﻰ ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ. ﻛﻮﺩ 2.10
public class DemoEnumeration { public static void DemoCountdownForeach() { Countdown countdown = new Countdown(); countdown.StartCountdown = 5;
20
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
foreach (int n in countdown) { Console.WriteLine( n ); } foreach (int n in countdown) { Console.WriteLine( "{0} BIS", n ); } } // … } foreachﺋﯩﺸﻠﯩﺘﯩﻠﮕﻪﻧﺪﻩ ،ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤـﺎﻥ ﺋﯩﭽﻜـﻰ ﻗﯩـﺴﯩﻤﺪﺍ ﭼﺎﺭﻻﻧﻐﯘﭼﯩﻨﯩـﯔ GetEnumerator ﻣﯧﺘــﻮﺩﯨﻨﻰ ﭼﺎﻗﯩﺮﯨــﭗ IEnumeratorﺋﯧﻐﯩﺰﯨﻐــﺎ)ﭼﺎﺭﻻﻧﻐﯘﭼﯩﻨﯩــﯔ( ﺋﯧﺮﯨــﺸﻜﻪﻧﺪﯨﻦ ﻛﯧــﻴﯩﻦ ﮬﻪﺭﺑﯩــﺮ ﺋﺎﻳﻼﻧﻤﯩﺪﯨﻦ ﺑﯘﺭﯗﻥ MoveNextﻣﯧﺘﻮﺩﯨﻨﻰ ﭼﺎﻗﯩﺮﯨـﺪﯗ .ﻟـﯧﻜﯩﻦ foreach) ،ﺋﯩﻠﯩﺘﯩﻠﮕﻪﻧـﺪﻩ( Reset ﻣﯧﺘﻮﺩﻯ ﮬﻪﺭﮔﯩﺰ ﭼﺎﻗﯩﺮﯨﻠﻤﺎﻳﺪﯗ) .ﺋﺎﺧﯩﺮﻗﻰ ﭼﻪﻛﺘﯩﻦ ﺑﺎﺷﻘﺎ ﻗﺎﻳﺘﯩﺶ ﻣﻪﺳﯩﻠﯩﺴﯩﻨﻰ ﭼﺎﺭﻟﯩﻐﯘﭼﻰ ﺗـﯜﺭﺩﯨﻦ ﺋﯩﻜﻜﯩﻨﻰ ﻗﯘﺭﯗﺵ ﺋﺎﺭﻗﯩﻠﯩﻖ ﮬﻪﻝ ﻗﯩﻠﯩﺪﯗ( C# 2.0ﺩﺍ ﻳﯧﯖــﻰ ﻗﻮﺷــﯘﻟﻐﺎﻥ yieldﺟﯜﻣﻠﯩــﺴﻰ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﻛــﻮﺩ-ﺗﻪﺭﺟﯩﻤــﺎﻧﻨﻰ ﺋﺎﭘﺘﻮﻣﺎﺗﯩــﻚ ﮬﺎﻟــﺪﺍ IEnumeratorﺋﯧﻐﯩﺰﯨﻨـﻰ ﮬﺎﺳـﯩﻞ ﻗﯩﻠـﺪﯗﺭﻏﯩﻠﻰ ﺑﻮﻟﯩـﺪﯗ.
yieldﺟﯜﻣﻠﯩـﺴﯩﻨﻰ ﭘﻪﻗﻪﺕ
return
ﻳــﺎﻛﻰ breakﺟﯜﻣﻠﯩــﺴﯩﻨﯩﯔ ﺋﺎﻟﺪﯨــﺪﯨﻼ ﺑﯩﯟﺍﺳــﺘﻪ ﺋﯩــﺸﻠﻪﺗﻜﯩﻠﻰ ﺑﻮﻟﯩــﺪﯗ .ﻛــﻮﺩ 2.11ﺩﺍ ﺋﯩﻘﺘﯩــﺪﺍﺭﻯ CountdownEnumeratorﺗﯜﺭﻯ ﺑﯩﻠﻪﻥ ﻣﺎﺱ ﻛﯧﻠﯩﺪﯨﻐﺎﻥ ﺗﯜﺭ ﻗﯘﺭﯗﻟﯩﺪﯗ. ﻛﻮﺩ 2.11
public class CountdownYield : IEnumerable { public int StartCountdown; public IEnumerator GetEnumerator() { for (int i = StartCountdown ‐ 1; i >= 0; i‐‐) { yield return i; } } } ﻟﻮﮔﯩﻜﺎ ﻧﯘﺧﺘﯩﺴﯩﺪﯨﻦ ﺋﯧﻠﯩﭗ ﺋﯧﻴﺘﻘﺎﻧﺪﺍ yield return ،ﺟﯜﻣﻠﯩﺴﻰ ﺋﯩﺠـﺮﺍ ﻣﻪﺷـﻐﯘﻻﺗﯩﻨﻰ ﯞﺍﻗﯩﺘﻠﯩـﻖ ﺗﻮﺧﺘﯩﺘﯩــﭗ ﻗﻮﻳــﯘﺵ ﺑﯩــﻠﻪﻥ ﺑــﺎﺭﺍﯞﻩﺭ ﺑﻮﻟــﯘﭖ MoveNext ،ﻛﯧﻴﯩﻨﻜــﻰ ﻗﯧــﺘﯩﻢ ﭼﺎﻗﯩﺮﯨﻠﻐﺎﻧــﺪﺍ ﺋﺎﻧــﺪﯨﻦ ﺩﺍﯞﺍﻣﻠﯩــﺸﯩﺪﯗ .ﺷﯘﻧﯩــﺴﻰ ﺋﯧــﺴﯩﯖﯩﺰﺩﻩ ﺑﻮﻟــﺴﯘﻥ ،ﭘﯜﺗﻜــﯜﻝ ﭼــﺎﺭﻻﺵ ﺟﻪﺭﻳﺎﻧﯩــﺪﺍ GetEnumerator ﻣﯧﺘﻮﺩﻯ ﭘﻪﻗﻪﺕ ﺑﯩﺮﻻ ﻗﯧﺘﯩﻢ ﭼﺎﻗﯩﺮﯨﻠﯩﭗ IEnumeratorﺋﯧﻐﯩﺰﯨﻨﻰ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ ﺗﯜﺭ ﻗـﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﯨــﺪﯗ .ﭘﻪﻗﻪﺕ ﻣﯘﺷــﯘ ﺗــﯜﺭﻻ yieldﺟﯜﻣﻠﯩــﺴﯩﻨﻰ ﺋــﯚﺯ ﺋﯩﭽﯩــﮕﻪ ﺋﺎﻟﻐــﺎﻥ ﻣﯧﺘــﻮﺩ ﺧــﯘﻟﻘﯩﻨﻰ ﮬﻪﻗﯩﻘﯩــﻲ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ ﺑﻮﻟﯩﺪﯗ.
21
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
yieldﺟﯜﻣﻠﯩﺴﯩﻨﻰ ﺋﯚﺯ ﺋﯩﭽﯩﮕﻪ ﺋﺎﻟﻐﺎﻥ ﻣﯧﺘﻮﺩ » «interator, 迭代器ﺩﻩﭖ ﺋﺎﺗﯩﻠﯩﺪﯗ )ﭼﺎﺭﻟﯩﻐﯘﭼﻰ، ﻳﻪﻧﻰ ﺑﯩﺮﺩﯨﻦ-ﺑﯩﺮﺩﯨﻦ ﺋﯧﻠﯩﭗ ﺗﻪﻛﺸﯜﺭﮔﯜﭼﻰ( .ﺑﯩﺮﺩﺍﻧﻪ interatorﺑﯩﺮﻗﺎﻧﭽﻪ yieldﺟﯜﻣﻠﯩﺴﯩﻨﻰ ﺋﯚﺯ ﺋﯩﭽﯩﮕﻪ ﺋﺎﻻﻻﻳﺪﯗ .ﻛﻮﺩ 2.12ﺩﯨﻜﯩﺪﻩﻙ ﻳﯧﺰﯨﺶ ﻗﺎﺋﯩﺪﯨﮕﻪ ﻣﯘﺗﻠﻪﻕ ﺋﯘﻳﻐﯘﻥ ﺑﻮﻟﯘﭖ ،ﺋﯩﻘﺘﯩﺪﺍﺭ ﺟﻪﮬﻪﺗﺘﻪ ﺋﺎﻟﺪﯨﻨﻘﻰ ﻣﯩﺴﺎﻟﺪﯨﻜﻰ CountdownYieldﺗﯜﺭﯨﻨﯩﯔ StartCountdownﺧﺎﺳﻠﯩﻘﯩﻨﯩﯔ 5 ﺩﯨﻦ ﺑﺎﺷﻼﻧﻐﺎﻥ ﮬﺎﻟﯩﺘﻰ ﺑﯩﻠﻪﻥ ﺑﺎﺭﺍﯞﻩﺭ. ﻛﻮﺩ 2.12
public class CountdownYieldMultiple : IEnumerable { public IEnumerator GetEnumerator() { yield return 4; yield return 3; yield return 2; yield return 1; yield return 0; } } IEnumeratorﻧﯩــﯔ ﻛﯚﭘﻤــﺎﺱ ﻧﯘﺳﺨﯩــﺴﯩﻨﻰ ﻗــﻮﻟﻠﯩﻨﯩﺶ ﺋــﺎﺭﻗﯩﻠﯩﻖ CountdownYieldﺗﯜﺭﯨﻨﯩــﯔ ﻛﯜﭼﻠـﯜﻙ ﺗﯩﭙﻼﻧﻐـﺎﻥ ) (strongly typed, 强类型ﻧﯘﺳﺨﯩـﺴﯩﻨﻰ ﮬﯘﺟﯘﺗﻘـﺎ ﭼﯩﻘـﺎﺭﻏﯩﻠﻰ ﺑﻮﻟﯩـﺪﯗ. ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 2.13
public class CountdownYieldTypeSafe : IEnumerable { public int StartCountdown; IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public IEnumerator GetEnumerator() { for (int i = StartCountdown ‐ 1; i >= 0; i‐‐) { yield return i; } } } ﻛﯜﭼﻠﯜﻙ ﺗﯩﭙﻼﻧﻐﺎﻥ ﻧﯘﺳﺨﯩﺴﯩﺪﺍ ﺋﯩﻜﻜﻰ ﺩﺍﻧﻪ GetEnumeratorﻣﯧﺘﻮﺩﻯ ﺋﯧﻨﯩﻘﻼﻧﻐﺎﻥ ﺑﻮﻟـﯘﭖ ،ﺑﯩـﺮﻯ ﻛﯚﭖ ﻣـﺎﺱ ﺑﻮﻟﻤﯩﻐـﺎﻥ ﻛﻮﺩﻻﺭﻏـﺎ ) IEnumerableﻧـﻰ ﻗﺎﻳﺘﯘﺭﯨـﺪﯨﻐﺎﻥ( ﻣـﺎﺱ ﻛﯧﻠﯩـﺪﯗ ،ﻳﻪﻧﻪ ﺑﯩـﺮﻯ ﺑﻮﻟﺴﺎ ﻛﯜﭼﻠﯜﻙ ﺗﯩﭙﻼﻧﻐﯩﻨﻰ.
22
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
C# 3.0ﻧﯩﯔ ﺧﯘﺳﯘﺳﯩﻴﻪﺗﻠﯩﺮﻯ varﺧﺎﺱ ﺳﯚﺯﻯ ﻳﯧﯖﯩــﺪﯨﻦ ﻗﻮﺷــﯘﻟﻐﺎﻥ varﺧــﺎﺱ ﺳــﯚﺯﻯ ﺋــﺎﺭﻗﯩﻠﯩﻖ ،ﺗﯩﭙــﻰ ﺋﯧﻨﯩــﻖ ﺑﻮﻟﻤﯩﻐــﺎﻥ ﺋﯚﺯﮔﻪﺭﮔــﯜﭼﻰ ﻣﯩﻘ ـﺪﺍﺭ ﺋﯧﻨﯩﻘﻼﺷــﻘﺎ ﺑﻮﻟﯩــﺪﯗ var .ﺑﯩــﻠﻪﻥ ﺑﺎﺷــﻘﺎ »ﺋﯧﻨﯩــﻖ ﺗﯩــﭙﻼﺭ« ﺋﺎﺭﯨــﺴﯩﺪﯨﻜﻰ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺷــﻨﻰ
.NET
ﻗﯘﺭﯗﻟﻤﯩــﺴﻰ ﺋﺎﭘﺘﻮﻣﺎﺗﯩــﻚ ﺑﯧﺠﯩﺮﻩﻟﻪﻳــﺪﯗ .ﺷــﯘﻧﻰ ﺋﻪﺳــﻜﻪﺭﺗﯩﺶ ﺯﯙﺭﯛﺭﻛــﻰ var ،ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﯧــﻨﯩﻘﻼﺵ objectﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﯧﻨﯩﻘﻼﺷﻘﺎ ﺑﺎﺭﺍﯞﻩﺭ ﺋﻪﻣﻪﺱ .ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻣﯩﺴﺎﻝ ﺑﯘﻧﯩﯖﻐﺎ ﺋﯩﺴﭙﺎﺕ ﺑﻮﻻﻻﻳﺪﯗ:
;var a = 2 ﭘﯜﺗﯜﻥ ﺳﺎﻥ ﺗﯩﭙﻠﯩﻖ ﻗﯩﻠﯩﭗ ﺋﯧﻨﯩﻘﻼﻧﺪﻯ // ;object b = 2 ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﺗﯩﭗ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭙﻘﺎ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﻟﺪﻯ ،ﺳﻪﺭﭘﯩﻴﺎﺗﻰ ﻳﯘﻗﯩﺮﻯ // ;int c = a ﮬﯩﭻ ﻗﺎﻧﺪﺍﻕ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻳﯜﺯ ﺑﻪﺭﻣﻪﻳﺪﯗ ،ﺗﯧﺰ // ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭗ ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﺗﯩﭙﻘـﺎ ﻣﻪﺟﺒـﯘﺭﻯ ﺋﺎﻟﻤﺎﺷـﯘﺗﯘﺭﯗﻟﯩﺪﯗ ،ﺳـﻪﺭﭘﯩﻴﺎﺕ int d = (int) b; // ﻳﯘﻗﯩﺮﻯ
varﻧﯩﯔ ﮬﻪﻗﯩﻘﯩﻲ ﺗﯩﭙﯩﻨﯩﯔ ﻗﺎﻧﺪﺍﻕ ﺑﻮﻟﯩﺸﻰ ﺋﻪﻣﻪﻟﯩﻲ ﺋﻪﮬﯟﺍﻟﻐﺎ ﻗﺎﺭﺍﭖ ﺑﯧﻜﯩﺘﯩﻠﯩﺪﯗ
int a = 5; var b = a; ﺑﯘ ﺋﯩﻜﻜﻰ ﺧﯩﻞ ﺋﯧﻨﯩﻘﻼﺵ ﺑﺎﺭﺍﯞﻩﺭ
int a = 5; int b = a; C#ﺗﯩﻠﯩـــﺪﺍ ﺗﯩﭙﻼﺭﻧﯩـــﯔ ﺗـــﯜﺭﻟﯩﺮﻯ ﺷـــﯘﻧﭽﯩﻠﯩﻚ ﺗﻮﻟـــﯘﻕ ﺗﯘﺭﯗﻗﻠـــﯘﻕ ﻳﻪﻧﻪ ﻧﯧﻤﯩـــﺸﻘﺎ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﻨﯩـــﯔ ﺋﻮﻗﯘﺷــﭽﺎﻧﻠﯩﻘﯩﻨﻰ ﺗﯚﯞﻩﻧﻠﯩﺘﯩﯟﯦﺘﯩــﺪﯨﻐﺎﻥ varﺧــﺎﺱ ﺳــﯚﺯﯨﻨﻰ ﺋﯩــﺸﻠﯩﺘﯩﻤﯩﺰ؟
ﻗﺎﺭﯨﻤﺎﻗﻘــﺎ varﮬــﻮﺭﯗﻥ
ﭘﺮﻭﮔﺮﺍﻣﻤﯩﻼﺭﻧﯩــﯔ ﺋﯧﮫﺘﯩﻴــﺎﺟﻰ ﺋﯜﭼــﯜﻥ ﻻﻳﮫﯩﻴﻪﻟﻪﻧﮕﻪﻧــﺪﻩﻙ ﺗﯘﺭﺳــﯩﻤﯘ ،ﺋﻪﻣﻪﻟﯩﻴﻪﺗــﺘﻪ ﺋــﯘ »ﻧﺎﻣــﺴﯩﺰ ﺋﯚﺯﮔﻪﺭﮔﯜﭼﻰ ﻣﯩﻘﺪﺍﺭ«)ﻛﯧﻴﯩﻦ ﺳﯚﺯﻟﯩﻨﯩﺪﯗ( ﺋﯧﻨﯩﻘﻼﺷﻨﯩﯔ ﺑﯩﺮﺩﯨﻦ -ﺑﯩﺮ ﻳﻮﻟﻰ. ﺑــﯘ ﻳﻪﺭﺩﯨﻜــﻰ varﺗﯩــﭗ -ﺑﯩﺨﻪﺗﻪﺭﻟﯧﻜﯩﻨ ـﻰ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﻏﺎﻧﻠﯩﻘﻰ ﺋﯜﭼــﯜﻥ Vsiaul Basicﺩﯨﻜــﻰ varﺧﺎﺱ ﺳﯚﺯﯨﺪﯨﻦ ﭘﻪﺭﻗﻠﯩﻨﯩﺪﯗ)ﻛﯚﭖ ﻛﯜﭼﻠﯜﻙ(. Varﺗﯩﭙﯩﻨﻰ ﭘﻪﻗﻪﺕ ﻳﻪﺭﻟﯩﻚ ﺋﻮﺭﯗﻧﺪﯨﻼ ﺋﯩﺸﻠﯩﺘﯩﺸﻜﻪ ﺑﻮﻟﯩﺪﯗ .ﺋﯘﻧﻰ ﺗﯜﺭﻧﯩﯔ ﻣﯧﺘﻮﺩﻻﺭﻧﯩﯔ ﭘـﺎﺭﺍﻣﯧﺘﯩﺮﻯ ﻳﺎﻛﻰ ﻗﺎﻳﺘﯘﺭﻣﺎ ﻗﯩﻤﻤﯩﺘﯩﻨﯩﯔ ﺗﯩﭙﻰ ﺋﻮﺭﻧﯩﺪﺍ ﺋﯩﺸﻠﯩﺘﯩﺸﻜﻪ ﺑﻮﻟﻤﺎﻳﺪﯗ. ﺗﻮﻏﺮﺍ ﺋﯩﺸﻠﯩﺘﯩﺶ ﺋﯘﺳﯘﻟﻰ: ﻛﻮﺩ 2
public void ValidUse( decimal d ) { var x = 2.3; // double var y = x; // double var r = x / y; // double var s = "sample"; // string var l = s.Length; // int var w = d; // decimal
23
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
var p = default(string); // string } ﺧﺎﺗﺎ ﺋﯩﺸﻠﯩﺘﯩﺶ ﺋﯘﺳﯘﻟﻰ: ﻛﻮﺩ 3
class VarDemo { ﺗﯜﺭ ﻳﺎﻛﻰ ﺋﯧﻐﯩﺰﻻﺭﻧﯩﯔ ﺧﺎﺳﻠﯩﻘﻰ ﺳﯜﭘﯩﺘﯩﺪﻩ ﺋﯩﺸﻠﯩﺘﯩﺸﻜﻪ ﺑﻮﻟﻤﺎﻳﺪﯗ // var k =0; ﭘﺎﺭﺍﻣﯧﺘﯩﺮﺩﺍ ﺋﯧﻨﯩﻖ ﺗﯩﭙﻰ ﺑﯧﻜﯩﺘﯩﻠﯩﺸﻰ ﻛﯧﺮﻩﻙ // public void InvalidUseParameter( var x ){} ﻗﺎﻳﺘﯘﺭﻣﺎ ﻗﯩﻤﻤﻪﺕ ﺗﯩﭙﻰ ﺋﯧﻨﯩﻖ ﺑﻮﻟﯘﺷﻰ ﻛﯧﺮﻩﻙ // public var InvalidUseResult() { return 2; } public void InvalidUseLocal() { var x; ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﻠﯩﻖ ﺧﺎﺗﺎﻟﯩﻖ ،ﺗﻪﯕﻠﯩﻚ ﺑﻪﻟﮕﯩﺴﻰ ﺑﻮﻟﯘﺷﻰ ﻛﯧﺮﻩﻙ // ;var y = null ' 'nullﻧﯩﯔ ﻗﺎﻳﺴﻰ ﺗﯩﭗ ﺋﯩﻜﻪﻧﻠﯧﻜﯩﻨﻰ ﺑﯩﻠﻪﻟﻤﻪﻳﺪﯗ// } // … }
ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ C#ﺑﻮﻟﺴﺎ ﺋﻮﺑﯩﻜﺘﯩﭙﻘﺎ ﻳﯜﺯﻟﻪﻧﮕﻪﻥ ﺗﯩﻞ ﺑﻮﻟﯘﭖ ،ﺋﺎﺗﺎ ﺗـﯜﺭﮔﻪ ﺑـﺎﻻ ﺗـﯜﺭﻧﻰ ﯞﺍﺭﯨـﺴﻠﯩﻖ ﻗﯩﻠـﺪﯗﺭﯗﭖ ﻳﯧﯖـﻰ ﻣﯧﺘﻮﺩﻻﺭﻧﻰ ﻗﻮﺷﯘﺵ ﻳﺎﻛﻰ ﺋﻪﺳﻠﻰ ﺑﺎﺭ ﺑﻮﻟﻐـﺎﻥ ﻣﯧﺘـﻮﺩﻻﺭﻧﻰ ﻗﺎﻳﺘـﺎ ﻳـﯧﯖﯩﻼﺵ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﺋﺎﺗـﺎ ﺗﯜﺭﻧﯩـﯔ ﺋﯩﻘﺘﯩــﺪﺍﺭﯨﻨﻰ ﺋﺎﺷــﯘﺭﯗﺵ ﻣﻪﻗــﺴﯩﺘﯩﮕﻪ ﻳﻪﺗﻜﯩﻠــﻰ ﺑﻮﻟﯩــﺪﯗ .ﺑﯩــﺮﺍﻕ »ﺑﯩﺨﻪﺗﻪﺭﻟﯩــﻚ« ﺑﯩــﻠﻪﻥ »ﺟــﺎﻧﻠﯩﻖ ﺋﯩــﺸﻠﯩﺘﯩﺶ« ﺑــﯘ ﺧﯩــﻞ ﻣﻪﺳــﯩﻠﯩﻠﻪﺭﻧﻰ ﮬﻪﻝ ﻗﯩﻠﯩــﺸﺘﯩﻜﻰ ﺋﯩﻜﻜــﻰ ﻗــﺎﺭﻣﯘ-ﻗﺎﺭﺷــﻰ ﺋﺎﻣﯩــﻞ ﺑﻮﻟــﯘﭖ ﻛﯧﻠﯩﯟﺍﺗﯩﺪﯗ. C#3.0ﺩﻩ ﻧﯚﯞﻩﺗﺘﻪ ﺑﺎﺭ ﺑﻮﻟﻐﺎﻥ ) .Netﻧﯩﯔ ﺋﯚﺯﯨﺪﻩ ﺑﺎﺭ ﺑﻮﻟﻐﺎﻧﻠﯩﺮﯨﻤﯘ ﺷﯘ( ﺗﯜﺭ )ﺗﯩﭙﻼﺭﻣـﯘ ﺷـﯘ( ﻻﺭﻏـﺎ ﻳﯧﯖﻰ ﺗﯜﺭﻧﻰ ﯞﺍﺭﯨﺴﻠﯩﻖ ﻗﯩﻠﺪﯗﺭﻣﺎﻱ ﺗﯘﺭﯗﭖ ﻳﯧﯖﻰ ﺋﯩﻘﺘﯩﺪﺍﺭ ﻗﻮﺷﯘﺷﻘﺎ ﻳﻮﻝ ﻗﻮﻳﯘﻟﻐﺎﻥ ﯞﻩ ﻣﯘﻧﺎﺳـﯩﯟﻩﺗﻠﯩﻚ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﯗﺵ ﻗﺎﺋﯩﺪﯨﻠﯩﺮﻯ ﺑﻪﻟﮕﯩﻠﻪﻧﮕﻪﻥ .ﻣﻪﺳﯩﻠﻪﻥ ﭘﯜﺗﯜﻥ ﺳﺎﻥ ﺗﯩﭙﻰ intﻧﻰ ﻣﯩﺴﺎﻟﻐﺎ ﺋﺎﻟﺴﺎﻕ: ﻛﻮﺩ 4
int i =5; Int j = i+1; //j == 6 int t = i‐1; //t == 4
24
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺑﯘ ﺋﯜﭺ ﻗﯘﺭ ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﮬﻪﻣﻤﯩﻤﯩﺰﮔﻪ ﭼﯜﺷﯜﻧﯜﺷﻠﯜﻙ .ﻳﯘﻗﯩﺮﯨﻘﻰ ﺟﯜﻣﻠﯩﻠﻪﺭﻧﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻳﻮﻝ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﯩﻠﻰ ﺑﻮﻻﻣﺪﯗ ﺩﻩﭖ ﭘﻪﺭﻩﺯ ﻗﯩﻠﯩﭗ ﺑﺎﻗﺎﻳﻠﻰ: ﻛﻮﺩ 5
int i =5; Int j = i.Increase(); // j == 6 int t = i.Decrease(); // t == 4 ﺑﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ intﺗﯩﭙﯩﻨﯩﯔ ﭼﻮﻗﯘﻡ ﺋﯚﺯ ﻗﯩﻤﻤﯩﺘﯩﻨﻰ ﺑﯩﺮ ﺋﺎﺷﯘﺭﯗﭖ ﻳﺎﻛﻰ ﺑﯩﺮ ﺗﯚﯞﻩﻧﻠﯩﺘﯩـﭗ ﻗـﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﻩﻟﻪﻳــﺪﯨﻐﺎﻥ )(Increaseﯞﻩ )( Decreaseﻧــﺎﻣﻠﯩﻖ )ﻳــﺎﻛﻰ ﺑﺎﺷــﻘﺎ ﻧــﺎﻣﻠﯩﻖ( ﻣﯧﺘــﻮﺩﻟﯩﺮﻯ ﺑﻮﻟﯘﺷــﻰ ﻛﯧــــﺮﻩﻙ .ﻟــــﯧﻜﯩﻦ ﺋﻪﺳــــﻠﻰ ﻗﯘﺭﯗﻟﻤﯩــــﺪﺍ intﻧﯩــــﯔ ﺑــــﯘ ﺋﯩﻘﺘﯩــــﺪﺍﺭﻟﯩﺮﻯ ﺗﻪﻣﯩــــﻨﻠﻪﻧﻤﯩﮕﻪﻥ .ﺑﯩــــﺰ ﺩﻩﯞﻩﺗﻘــﺎﻥ»ﻛﯧﯖﻪﻳــﺘﯩﻠﮕﻪﻥ ﻣﯧﺘــﻮﺩ« ﺋﯩﻘﺘﯩــﺪﺍﺭﻯ ﺩﻩﻝ ﻣﯘﺷــﯘﻧﯩﯖﺪﻩﻙ ﻣﻪﺳــﯩﻠﯩﻠﻪﺭﮔﻪ ﺗﺎﻗﺎﺑﯩــﻞ ﺗــﯘﺭﯗﺵ ﻣﻪﻗﺴﯩﺘﯩﺪﻩ ﻗﻮﺷﯘﻟﻐﺎﻥ. ﺋﻪﻣﺪﻯ ﺑﯩﺰ intﻧﻰ ﻛﯧﯖﻪﻳﺘﯩﭗ ﺑﺎﻗﺎﻳﻠﻰ .ﻧـﯚﯞﻩﺗﺘﯩﻜﻰ ﺗـﯜﺭﯨﻤﯩﺰﮔﻪ) (projectﻳﯧﯖﯩـﺪﯨﻦ ﺗـﯜﺭ ﻗﻮﺷـﯘﭖ ﺋﯘﻧﯩــﯔ ﺋﯩــﺴﯩﻤﯩﻨﻰ IntegerExtensionﺩﻩﭖ ﻗﻮﻳــﺎﻳﻠﻰ).ﺧﺎﻟﯩﻐــﺎﻧﭽﻪ ﻗﻮﻳــﺴﯩﯖﯩﺰ ﺑﻮﻟﯩــﺪﯗ( .ﺋﯘﻧﯩــﯔ ﻣﻪﺯﻣﯘﻧﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺑﻮﻟﺴﯘﻥ: ﻛﻮﺩ 6
namespace ConsoleApplication5 { static class IntegerExtension { public static int Increase(this int i) { return i + 1; } public static int Decrease(this int i) { return i ‐ 1; } } ﺋﻪﻣﺪﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺭﻩﺳﯩﻤﮕﻪ ﻗﺎﺭﺍﯓ:
25
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺩﯦﻤﻪﻙIncrease() ،ﺑﯩﻠﻪﻥ )( Decreaseﺋﻪﻣﺪﻯ intﻧﯩﯔ »ﺑﻮﻟﯘﭖ ﻛﻪﺗﺘﻰ«. ﻳﯧــﺰﯨﺶ ﻗﺎﺋﯩﺪﯨــﺴﯩﻨﻰ ﺗﯧﺨﯩﻤــﯘ ﺗﻪﭘــﺴﯩﻠﯩﻴﺮﻩﻙ ﭼﯜﺷــﯜﻧﯜﺵ ﺋﯜﭼــﯜﻥ )( Increaseﻣﯧﺘــﻮﺩﯨﻨﻰ ﻣﯩــﺴﺎﻟﻐﺎ ﺋﺎﻻﻳﻠﻰ .ﻛﯧﯖﻪﻳﺘﯩﺶ ﺋﯘﺳﯘﻟﯩﻨﯩﯔ ﺋﻮﺭﺗﺎﻕ ﻗﯘﺭﯗﻟﻤﯩﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺑﻮﻟﯩﺪﯗ:
ﻳﯘﻗﯩﺮﯨﻘﻰ ﻗﯘﺭﯗﻟﻤﯩﺪﯨﻜﻰ ﺋﺎﺳﺘﯩﻐﺎ ﻗﯩﺰﯨﻞ ﺳﯩﺰﯨﻖ ﺳﯩﺰﯨﻠﻐﺎﻧﻠﯩﺮﯨﻨﻰ ﺋﯚﺯ ﭘﯧﺘﻰ ﻳﯧﺰﯨﺸﯩﯖﯩﺰ ﻛﯧﺮﻩﻙ .ﻳﯧﺸﯩﻞ ﺳﯩﺰﯨﻖ ﺳﯩﺰﯨﻠﻐﺎﻧﻠﯩﺮﻯ ﺑﻮﻟﺴﺎ ﺋﯧﮫﺘﯩﻴﺎﺟﻐﺎ ﻗﺎﺭﺍﭖ ﺋﯚﺯﮔﯜﺭﯨﺪﯗ .ﺩﯦﻤﻪﻙ:
z
ﻛﯧﯖﻪﻳـــﺘﯩﺶ ﻣﯧﺘـــﻮﺩﻯ ﯞﻩ ﺋـــﯘﻧﻰ ﺋـــﯚﺯ ﺋﯩﭽﯩـــﮕﻪ ﺋﺎﻟﻐـــﺎﻥ ﺗـــﯜﺭ ﭼﻮﻗـــﯘﻡ ﺗﯘﺭﺍﻗﻠﯩـــﻖ ﺑﻮﻟﯘﺷـــﻰ
ﻛﯧﺮﻩﻙ).(static
z
ﻛﯧﯖﻪﻳـــﺘﯩﺶ ﻣﯧﺘﻮﺩﯨﻨﯩـــﯔ ﭘـــﺎﺭﺍﻣﯧﺘﯩﺮﻯ ﺋﺎﻟـــﺪﯨﻐﺎ thisﺧـــﺎﺱ ﺳـــﯚﺯﯨﻨﻰ ﻗﻮﺷـــﯘﺵ ﺋـــﺎﺭﻗﯩﻠﯩﻖ
ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪﻛﭽﻰ ﺑﻮﻟﻐـﺎﻥ ﺗﯩﭙﻨـﻰ ﺑﻪﻟﮕﯩﻠﯩـﺸﯩﻤﯩﺰ ﻛﯧـﺮﻩﻙ .ﻣﻪﺳـﯩﻠﻪﻥ :ﻳﯘﻗـﺎﺭﻗﻰ ﻣﯩـﺴﺎﻟﺪﺍ intﺗﯩﭙﯩﻨـﻰ ﻛﯧﯖﻪﻳﺘﯩﺪﯗ.
z
ﻛﯧﯖﻪﻳﺘﯩﺶ ﻣﯧﺘﻮﺩﯨﻨﯩﯔ ﻗﺎﻳﺘﯘﺭﻣﺎ ﻗﯩﻤﻤﻪﺕ ﺗﯩﭙﻰ ﺧﺎﻟﯩﻐﺎﻧﭽﻪ ﺑﻮﻟﺴﺎ ﺑﻮﻟﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ:
26
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﻮﺩ 7
public static float Devide(this int i) { return (float)i / 2; } ﺑﯘ ﻣﯧﺘﻮﺩ intﺗﯩﭙﯩﻐﺎ ﺋﯚﺯ ﻗﯩﻤﻤﯩﺘﯩﻨﯩﯔ ﻳﯧﺮﯨﻤﻰ ﻗﺎﻳﺘﯘﺭﯗﺵ ﺋﯩﻘﺘﯩـﺪﺍﺭﯨﻨﻰ ﻗﻮﺷـﯩﺪﯗ .ﺋﻪﻟـﯟﻩﺗﺘﻪ ،ﭘﯜﺗـﯜﻥ ﺳﺎﻧﻨﻰ ﺋﯩﻜﻜﯩﮕﻪ ﺑﯚﻟﺴﻪﻙ ﻛﻪﺳﯩﺮ ﺳﺎﻧﻤﯘ ﭼﯩﻘﯩﺪﯗ .ﺷﯘﯕﺎ ﻗﺎﻳﻤﺎ ﻗﯩﻤﻤﻪﺕ ﺗﯩﭙﯩﻨﻰ floatﻗﯩﻠﺪﯗﻕ.
z
ﺑﯩﺮﺩﺍﻧﻪ ﻛﯧﯖﻪﻳﺘﯩﺶ ﺗﯜﺭﻯ ﺋﯩﭽﯩﮕﻪ ﺑﯩﺮﻗﺎﻧﭽﻪ ﺗﯩﭙﻨﯩﯔ ﻛﯧﯖﻪﻳﺘﯩﺶ ﻣﯧﺘﻮﺩﻟﯩﺮﯨﻨﻰ ﺋﺎﺭﻻﺵ ﻳـﺎﺯﻏﯩﻠﻰ
ﺑﻮﻟﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 8
static class MixedExtension { public static int Increase(this int i) { return i + 1; } public static float DoubleIt(this float f) { return f * f; } } intﺗﯩﭙﯩﻨﯩــﯔ ﻛﯧﯖﻪﻳــﺘﯩﺶ ﻣﯧﺘــﻮﺩﻯ )( Increaseﺑﯩــﻠﻪﻥ floatﺗﯩﭙﯩﻨﯩــﯔ ﻛﯧﯖﻪﻳــﺘﯩﺶ ﻣﯧﺘــﻮﺩﻯ )( DoubleItﺑﯩــﺮ ﺗــﯜﺭ ﺋﯩﭽﯩــﮕﻪ ﻳﯧﺰﯨﻠــﺪﻯ .ﻛﯧﻴﯩﻨﻜﯩــﺴﻰ ﺑﻮﻟــﺴﺎ floatﺗﯩﭙﯩﻐــﺎ ﺋــﯚﺯ ﻗﯩﻤﻤﯩﺘﯩﻨﯩــﯔ ﻛﯘﯞﺍﺩﯨﺮﺍﺗﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯗﺵ ﺋﯩﻘﺘﯩﺪﺍﺭﯨﻨﻰ ﻗﻮﺷﯩﺪﯗ.
z
ﻛﯧﯖﻪﻳﺘﯩﺶ ﻣﯧﺘﻮﺩﻯ ﻛﯚﭖ ﭘﺎﺭﺍﻣﯩﺘﯧﺮﻧﻰ ﻗﻮﻟﻼﻳﺪﯗ.
ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﯩﺴﺎﻟﻼﺭﻧﯩﯔ ﮬﻪﻣﻤﯩـﺴﯩﺪﯨﻜﻰ ﺑﯩـﺰ ﻗﻮﺷـﻘﺎﻥ ﻛﯧﯖﻪﻳـﺘﯩﺶ ﻣﯧﺘﻮﺩﻟﯩﺮﯨـﺪﺍ ﺋﻪﻣﻪﻟﯩـﻲ ﭘﺎﺗﺎﻣﯧﺘﯩﺮﻻﺭ ﻳﻮﻕ .ﻣﻪﺳﯩﻠﻪﻥ )( . int j = i.Increaseﺑﯘ ﻗـﯘﺭﺩﺍ )( Increaseﻣﯧﺘـﻮﺩﻯ ﺑﯩـﺮ ﺋﯩــﺸﻨﻰ ﻗﯩﻠﯩــﺪﯗ ﺋﻪﻣﻤــﺎ ﺋﯘﻧﯩﯖﻐــﺎ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮ ﻳــﻮﻟﻼﭖ ﺑﻪﺭﻣﯩــﺪﯗﻕ Increase() .ﻣﯧﺘــﻮﺩﻯ ﺋﻪﺳــﻠﻰ ﻗﯩﻤﻤﯩــﺘﯩﮕﻪ ﺑﯩﺮﻧــﻰ ﻗﻮﺷــﯘﭖ ﻗــﺎﺗﯘﺭﯗﭖ ﺑﯧﺮﯨــﺪﯗ .ﺋﻪﮔﻪﺭ ﺑﯩــﺰ ﻣﻪﺯﻛــﯘﺭ ﻣﯧﺘــﻮﺩﺗﯩﻦ ﭘﺎﻳــﺪﯨﻠﯩﻨﯩﭗ ﺋﻪﺳــﻠﻰ ﻗﯩﻤﻤﻪﺗﻜﻪ ﺋﯜﭼﻨﻰ ﻗﻮﺷﻘﯘﺯﻣﺎﻗﭽﻰ ﺑﻮﻟﺴﺎﻕ ،ﻣﯘﻧﺪﺍﻕ ﻛﻮﺩ ﻳﯧﺰﯨﺸﯩﻤﯩﺰ ﻣﯘﻣﻜﯩﻦ: ﻛﻮﺩ 9
int i = 5; int j = i.Increase().Increase().Increase(); //j==8
27
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﻪﮔﻪﺭ ﺋﺎﺷﯘﺭﻣﺎﻗﭽﻰ ﺑﻮﻟﻐـﺎﻥ ﻗﯩﻤﻤﻪﺗﻨـﻰ ﭘﺎﺗـﺎﻣﯧﺘﯩﺮ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﻳـﻮﻟﻼﭖ ﺑﻪﺭﺳـﻪﻛﭽﯘ؟ ﺋﻪﻟـﯟﻩﺗﺘﻪ ﺑﻮﻟﯩـﺪﯗ. ﺑﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛﻮﺩ ﻳﺎﺯﯨﻤﯩﺰ: ﻛﻮﺩ 10
public static int Increase(this int i, int degree) { return i + degree; } ﺑﯩﺮﯨﻨﭽﻰ ﭘﺎﺭﺍﻣﺘﯧﺮﻯ »ﻣﯘﺷﯘ ﺗﯩﭙﻠﯩﻖ ﺋﯚﺯﯛﻡ« ﺩﯦﮕﻪﻥ ﻣﻪﻧﯩﺪﻩ ،ﺋﯩﻜﻜﻰ ﭘﺎﺭﺍﻣﯧﺘﯩﺮ ﺑﯩﺮ ﺩﺍﻧﻪ ﭘﯜﺗﯜﻥ ﺳﺎﻥ ﺗﯩﭙﻠﯩﻖ )ﺑﯘ ﻳﻪﺭﺩﯨﻜﻰ ﭘﺎﺗﺎﻣﯧﺘﯩﺮ ﺗﯩﭙﯩﻐﺎ ﭼﻪﻙ ﻳﻮﻕ( ﻗﯩﻤﻤﻪﺕ .ﻗﺎﻳﺘﯘﺭﻣﺎ ﻗﯩﻤﻤﻪﺕ ﺋﻪﺳﻠﻰ ﻗﯩﻤﻤﻪﺕ ﺑﯩﻠﻪﻥ ﺋﯩﻜﻜﯩﭽﻰ ﭘﺎﺗﺎﻣﯧﺘﯩﺮﺩﺍ ﺑﯧﺮﯨﻠﮕﻪﻥ ﻗﯩﻤﻤﻪﺗﻨﯩﯔ ﻳﯩﻐﯩﻨﺪﯨﺴﻰ .ﺋﻪﻣﺪﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛﻮﺩ ﻳﺎﺯﺍﻻﻳﻤﯩﺰ. ﻛﻮﺩ 11
int i = 5; int j = i.Increase(3); //j == 5+3 == 8 ﻳﻪﻧﻪ ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 12
static class MixedExtension { public static string ExtendedTrim(this string s, char c) { return s.Trim(new char[] { c }); } } ﻣﯘﻧﺎﺳﯩﭗ ﺋﯩﺸﻠﯩﺘﯩﺶ: ﻛﻮﺩ 13
;"ﻛﯩﺮﺩﯨﻢ ﻳﺎﺷﻘﺎ.............ﻣﻪﻥ" =string str1 "ﻛﯩﺮﺩﯨﻢ ﻣﻪﻧﻴﺎﺷﻘﺎ" == // str2
;)'string str2 = str1.ExtendedTrim('.
ﻳﯩﻐﯩﻨﭽﺎﻗﻠﯩﻐﺎﻧﺪﺍ ﺗﯜﺭ)ﻳﺎﻛﻰ ﺗﯩﭗ(ﻻﺭ ﺋﺎﺭﯨـﺴﯩﺪﯨﻜﻰ ﻣﯧﺘـﻮﺩ ﻛﯧﯖﻪﻳﺘﯩـﺸﻨﻰ ﺗﯚﯞﻩﻧـﺪﯨﻜﻰ ﻗﯧﻠﯩﭙﻼﺷـﺘﯘﺭﯗﺵ ﻣﯘﻣﻜﯩﻦ: ﻛﻮﺩ 2.25
public class A { public virtual void X() {} } public class B : A {
28
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
public override void X() {} public void Y() {} } static public class E { static void X( this A a ) {} static void Y( this A b ) {} public static void Demo() { A a = new A(); B b = new B(); A c = new B(); A.Xﻧﻰ ﭼﺎﻗﯩﺮﯨﺶ a.X(); // B.Xﻧﻰ ﭼﺎﻗﯩﺮﯨﺶ b.X(); // B.Xﻧﻰ ﭼﺎﻗﯩﺮﯨﺶ c.X(); // E.Yﻧﻰ ﭼﺎﻗﯩﺮﯨﺶ a.Y(); // B.Yﻧﻰ ﭼﺎﻗﯩﺮﯨﺶ b.Y(); // E.Yﻧﻰ ﭼﺎﻗﯩﺮﯨﺶ c.Y(); // } }
ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﻰ ﺩﻩﺳﻠﻪﭘﻠﻪﺷﺘﯜﺭﯛﺵ ﺋﯩﭙﺎﺩﯨﺴﻰ C#1.xﺩﻩ ﺧﺎﺳـــﻠﯩﻘﻼﺭﻧﻰ ﻳـــﺎﻛﻰ ﻳﻪﺭﻟﯩـــﻚ ﺋﯚﺯﮔﻪﺭﮔـــﯜﭼﻰ ﻣﯩﻘـــﺪﺍﺭﻻﺭﻧﻰ ﺑﯩـــﺮ ﺟـــﯜﻣﻠﻪ ﺋـــﺎﺭﻗﯩﻠﯩﻘﻼ ﺩﻩﺳﻠﻪﭘﻠﻪﺷﺘﯜﺭﯛﺷﻜﻪ ﺑﻮﻟﯩﺪﯗ.
int i = 3; string name = 'Unknown'; Customer c = new Customer( "Tom", 32 ); ﺑﯘﻧـــﺪﺍﻕ ﺩﻩﺳﻠﻪﭘﻠﻪﺷـــﺘﯜﺭﯛﺵ ﺋﯘﺳـــﯘﻟﯩﻐﺎ ﭼﺎﻗﯩﺮﯨﻠﻤـــﺎ ﺗﯩﭙﻘـــﺎ) (引用类型ﻗﻮﻟﻠﯩﻨﯩﻠﻐﺎﻧـــﺪﺍ ﺋﺎﻟـــﺪﯨﻦ ﺑﻪﻟﮕﯩﻠﻪﻧــﮕﻪﻥ ﻣــﺎﺱ ﮬﺎﻟــﺪﯨﻜﻰ ﻗﯘﺭﻏــﯘﭼﻰ ﻣﯧﺘــﻮﺩﻟﯩﺮﯨﻨﻰ ﺋﯩﺠــﺮﺍ ﻗﯩﻠﯩــﺪﯗ .ﻳــﯘﻗﯩﺮﯨﻘﻰ ﺋــﯜﭼﯩﻨﭽﻰ ﻗــﯘﺭ ﺋﯜﻧﯜﻣﻠﯜﻙ ﺑﻮﻟﯘﺷﻰ ﺋﯜﭼﯜﻥ ﭼﻮﻗﯘﻡ Customerﺗﯜﺭﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻳﯧﺰﯨﻠﻐﺎﻥ ﺑﻮﻟﯘﺷﻰ ﻛﯧﺮﻩﻙ.
public class Customer { public int Age; public string Name;
29
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
public string Country; public Customer( string name, int age ) { this.Name = name; this.Age = age; } // … } ﺩﯦـﻤﻪﻙ ﺋـﯘ ) new Customer( "Tom", 32 ﺩﻩﻙ ﺋﯩﺸﻠﯩﺘﯩـﺸﻜﻪ ﻣﯘﻧﺎﺳـﯩﭗ ﻗﯘﺭﻏـﯘﭼﻰ ﻣﯧﺘـﻮﺩﻧﻰ ﺗﻪﻳﻴﺎﺭﻟﯩﺸﻰ ﻛﯧﺮﻩﻙ .ﺑﯩﺮﺍﻕ ﺑﯘ ﻗﯘﺭﻏﯘﭼﯩﻨﯩﯔ ﺑﯩﺮ ﺋﺎﺟﯩﺰﻟﯩﻘﻰ ﺑﺎﺭ ﻳﻪﻧﻰ :ﻗﯘﺭﻏﺎﻥ ﭘﻪﻳﺘﺘﻪ nameﺑﯩﻠﻪﻥ ageﻧـﻰ ﭼﻮﻗـﯘﻡ ﻳـﻮﻟﻼﭖ ﺑﯧﺮﯨـﺸﯩﻤﯩﺰ ﻛﯧـﺮﻩﻙ .ﺋﻪﮔﻪﺭ Countryﺑﯩـﻠﻪﻥ nameﻻ ﺑﻮﻟﻐـﺎﻥ age ،ﺋـﻰ ﻗﯘﺭﯗﻕ ﺑﻮﻟﻐﯩﻨﯩﻨﻰ ﻗﯘﺭﯗﺵ ﺋﯜﭼﯜﻥ ﻳﺎﻛﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛـﻮﺩ ﻳﯧـﺰﯨﺶ ،ﻳـﺎﻛﻰ ﻣﯘﻧﺎﺳـﯩﭗ ﻗﯘﺭﻏـﯘﭼﻰ ﻣﯧﺘﻮﺩﯨﻨﻰ ﺗﻪﻣﯩﻨﻠﻪﺵ ﻛﯧﺮﻩﻙ. ﻛﻮﺩ 2.27
Customer customer = new Customer(); customer.Name = "Marco"; customer.Country = "Italy"; C#3.0ﺩﻩ ﻳﯘﻗﯩﺮﯨﻘﯩــﺪﻩﻙ ﻣﻪﺷــﻐﯘﻻﺗﻼﺭﻧﻰ ﺗﯧﺨﯩﻤــﯘ ﺋــﺎﺩﺩﻯ)ﻗﯩــﺴﻘﺎ( ﺟــﯜﻣﻠﯩﻠﻪﺭ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷﯘﺭﻏﯩﻠﻰ ﺑﻮﻟﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 2.28 ﺋﻮﺑﻴﯧﻜﯩﺘﻨﻰ ﺩﻩﺳﻠﻪﭘﻠﻪﺷﺘﯜﺭﯛﺷﺘﯩﻦ ﺋﺎﯞﺍﻝ ﺗﯜﺭﻧﯩﯔ ﻛﯚﯕﯜﻟﺪﯨﻜﻰ ﻗﯘﺭﻏﯘﭼﻰ ﻣﯧﺘﻮﺩﯨﻨﻰ ﻳﻮﺷﯘﺭﯗﻥ ﮬﺎﻟﺪﺍ ﭼﺎﻗﯩﺮﯨﺪﯗ //
Customer customer = new Customer { Name = "Marco", Country = "Italy" }; ﺋﻮﺑﻴﯧﻜﯩﺘﻨﻰ ﺩﻩﺳﻠﻪﭘﻠﻪﺷﺘﯜﺭﯛﺷﺘﯩﻦ ﺋﺎﯞﺍﻝ ﺗﯜﺭﻧﯩﯔ ﻛﯚﯕﯜﻟﺪﯨﻜﻰ ﻗﯘﺭﻏﯘﭼﻰ ﻣﯧﺘﻮﺩﯨﻨﻰ ﺋﺎﺷﻜﺎﺭﻩ ﮬﺎﻟﺪﺍ ﭼﺎﻗﯩﺮﯨﺪﯗ //
Customer customer = new Customer() { Name = "Marco", Country = "Italy" }; ﻟﯧﻜﯩﻦ ﺋﺎﻟﺪﯨﻨﻘﻰ ﺷﻪﺭﺕ ﺷﯘﻛﻰ ﺗﯩﺮﻧﺎﻕ ﺋﯩﭽﯩﺪﯨﻜﻰ ﺧﺎﺳﻠﯩﻘﻼﺭ ﭼﻮﻗﯘﻡ publicﺑﻮﻟﯘﺷﻰ ﻛﯧﺮﻩﻙ. ﺋﻪﮔﻪﺭ ﺗﯜﺭ ﻣﻪﻟـﯘﻡ ﭘﺎﺗـﺎﻣﯧﺘﯩﺮﻟﯩﻖ ﻗﯘﺭﻏـﯘﭼﻰ ﻣﯧﺘـﻮﺩﻻﺭﻧﻰ ﺗﻪﻣﯩـﻨﻠﯩﮕﻪﻥ ﺑﻮﻟـﺴﺎ ،ﻳـﯘﻗﯩﺮﯨﻘﻰ ﺟـﯜﻣﻠﯩﻠﻪﺭﻧﻰ ﻗﯘﺭﻏﯘﭼﻰ ﻣﯧﺘﻮﺩﻯ ﺋﺎﺳﺎﺳﯩﺪﺍ ﻳﺎﺯﻏﯩﻠﻰ ﺑﻮﻟﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 2.29
ﻛﯚﯕﯜﻟﺪﯨﻜﻰ ﺋﻪﻣﻪﺱ ﻗﯘﺭﻏﯘﭼﻰ ﻣﯧﺘﻮﺩﯨﻨﻰ ﺋﺎﺷﻜﺎﺭﻩ ﮬﺎﻟﺪﺍ ﭼﺎﻗﯩﺮﯨﺪﯗ //
Customer c2 = new Customer( "Paolo", 21 ) { Country = "Italy" }; c2ﻧﯩﯔ ﻳﯘﻗﯩﺮﯨﻘﻰ ﺋﯧﻨﯩﻘﻠﯩﻤﯩﺴﻰ ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﺗﯚﯞﻩﻧﻜﻰ ﺋﯩﻜﻜﻰ ﺟﯜﻣﻠﻪ ﺑﯩﻠﻪﻥ ﺑﺎﺭﺍﯞﻩﺭ
Customer c2 = new Customer( "Paolo", 21 ); ;"c2.Country = "Italy
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ: ﻣﻪﺳﯩﻠﻪﻥ.ﺑﯘ ﻗﺎﺋﯩﺪﻩ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻣﻪﺳﯩﻠﯩﻠﻪﺭﺩﻩ ﺗﯧﺨﯩﻤﯘ ﻛﯜﭼﯩﻨﻰ ﻛﯚﺭﺳﯩﺘﯩﺪﯗ ﻣﯘﻧﺎﺳﯩﯟﻩﺗﻠﯩﻚ ﺋﯩﻜﻜﻰ ﺗﯜﺭ ﺑﺎﺭ 2.30 ﻛﻮﺩ
public class Point { int x, y; public int X { get { return x; } set { x = value; } } public int Y { get { return y; } set { y = value; } } } public class Rectangle { Point tl, br; public Point TL { get { return tl; } set { tl = value; } } public Point BR { get { return br; } set { br = value; } } } ﺗﯜﺭﯨﺪﯨﻦ ﺑﯩﺮ ﺋﯧﻨﯩﻘﻼﺵ ﯞﻩ ﻗﯩﻤﻤﻪﺗﻠﯩﺮﯨﻨـﻰ ﺗﻮﻟـﺪﯗﺭﯗﺵRectangle ﯞﻩ ﺑﯘﺭﯗﻧﻘﻰ ﻧﻪﺷﯩﺮﻟﻪﺭﺩﻩC#2.0 ( ﺑﯘﻣﯘ ﺑﯩﺮ ﺧﯩﻞ ﻳﻮﻟﻰ،ﺋﯜﭼﯜﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺟﻪﺭﻳﺎﻥ ﻛﯧﺘﻪﺗﺘﻰ)ﺋﻪﻟﯟﻩﺗﺘﻪ
Rectangle rectangle2 = new Rectangle(); Point point1 = new Point(); point1.X = 0; point1.Y = 1; rectangle2.TL = point1; Point point2 = new Point(); point2.X = 2; point2.Y = 3; rectangle2.BR = point2; Rectangle rectangle1 = rectangle2;
ﻗــﺎﻧﭽﻪ ﻗــﯘﺭ ﺋــﺎﺭﻗﯩﻠﯩﻘﻼ ﻣﻪﻗــﺴﻪﺗﻜﻪ- ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﺑﯩــﺮ، ﻧﯩــﯔ ﻗﺎﺋﯩﺪﯨـﺴﯩﻨﻰ ﻗﻮﻟﻼﻧــﺴﺎﻕC#3.0 ﺋﻪﮔﻪﺭ ﻳﯧﺘﻪﻟﻪﻳﻤﯩﺰ 2.31 ﻛﻮﺩ
Rectangle r = new Rectangle { TL = new Point { X = 0, Y = 1 }, BR = new Point { X = 2, Y = 3 } }; ﻳﺎﻛﻰ
30
31
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
Rectangle r = new Rectangle { TL = { X = 0, Y = 1 }, BR = { X = 2, Y = 3 } }; ﺋﻪﮔﻪﺭ ﻗﯘﺭﻣﺎﻗﭽﻰ ﺑﻮﻟﻐﯩﻨﯩﯖﯩﺰ ﻣﻪﻟﯘﻡ ﺗﯜﺭﻧﯩﯔ ﺗﯩﺰﯨﻤﻠﯩﻜﻰ ﺑﻮﻟﺴﺎ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻗﺎﺋﯩﺪﻩ ﻳﻪﻧﯩﻼ ﻛﯜﭼﻜﻪ ﺋﯩﮕﻪ: ﻛﻮﺩ 2.32
List integers = new List { 1, 3, 9, 18 }; List list = new List { new Customer( "Jack", 28 ) { Country = "USA"}, new Customer { Name = "Paolo" }, new Customer { Name = "Marco", Country = "Italy" }, }; ArrayList integers = new ArrayList() { 1, 3, 9, 18 }; ArrayList list = new ArrayList { new Customer( "Jack", 28 ) { Country = "USA"}, new Customer { Name = "Paolo" }, new Customer { Name = "Marco", Country = "Italy" }, }; ﻳﯩﻐﯩﻨﭽﺎﻗﻠﯩﻐﺎﻧــﺪﺍ ﻳﯧﯖﯩــﺪﯨﻦ ﺗﻪﻣﯩــﻨﻠﻪﻧﮕﻪﻥ ﺋﯘﺳــﯘﻟﻼ ﺋــﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﻰ ﻗــﯘﺭﯗﺵ ﯞﻩ ﺩﻩﺳﻠﻪﭘﻠﻪﺷــﺘﯜﺭﯛﺵ ﻣﻪﺷﻐﯘﻻﺗﻠﯩﺮﯨﻨﻰ ﺋﺎﺩﺩﻯ ﺑﯩﺮ ﻳﺎﻛﻰ ﺑﯩﺮﻗﺎﻧﭽﻪ ﻓﯘﻧﻜﯩﺴﯩﻴﻪ ﺋﯩﭽﯩﮕﯩﻼ ﻣﯘﺟﻪﺳﺴﻪﻣﻠﻪﺷﺘﯜﺭﯛﭖ .ﺷﯘ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻛﻮﺩﯨﻤﯩﺰﻧﯩﯔ ﺋﻮﻗﯘﺷﭽﺎﻧﻠﯩﻘﯩﻨﻰ ﺯﻭﺭ ﺩﻩﺭﯨﺠﯩﺪﻩ ﻳﯘﻗﯩﺮﻯ ﻛﯚﺗﯜﺭﮔﻪﻥ.
ﻧﺎﻣﺴﯩﺰ ﺗﯩﭗ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﻰ ﻗﯘﺭﯗﺵ ﯞﻩ ﺩﻩﺳﻠﻪﭘﻠﻪﺷﺘﯜﺭﯛﺵ ﺋﯜﭼﯜﻥ ﺋﻪﻣـﺪﻯ ﻣﻪﺯﻛـﯘﺭ ﺋﻮﺑﻴﯧﻜﯩﺘﻨﯩـﯔ ﻗﺎﻳـﺴﻰ ﺗﯩﭙﻠﯩـﻖ ﺋﯩﻜﻪﻧﻠﯧﻜﯩﻨﻰ ﺑﯩﻠﯩﺸﻨﯩﯔ ﮬﺎﺟﯩﺘﻰ ﻗﺎﻟﻤﯩـﺪﻯ)ﺯﯙﺯﯛﺭ ﺗﯧﭙﯩﻠـﺴﺎ( .ﺑـﯘ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﻗﯘﺭﯗﻟﻐـﺎﻥ ﺋﻮﺑﻴﯧﻜﯩﺘﻨﯩـﯔ ﺗﯩﭙﻰ »ﻧﺎﻣﺴﯩﺰ ﺗﯩﭗ« ﺩﻩﭖ ﺋﺎﺗﯩﻠﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 2.33
Customer c1 = new Customer { Name = "Marco", Age=34 }; var c2 = new Customer { Name = "Paolo", Age=30 }; var c3 = new { Name = "Tom", Age = 31 }; var c4 = new { c2.Name, c2.Age }; var c5 = new { c1.Name, c1.Country }; var c6 = new { c1.Country, c1.Name };
32
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺑﯘ ﻳﻪﺭﺩﯨﻜﻰ c1ﺑﯩـﻠﻪﻥ c2ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩـﯔ ﺗﯩﭙـﻰ ﺑﻮﻟـﺴﺎ »ﻧـﺎﻣﻠﯩﻖ ﺗﯩـﭗ« ﻳﻪﻧـﻰ ﺋﯘﻻﺭﻧﯩـﯔ ﺗﯩﭙـﻰ .Customerﺑﯘ ﺋﯩﻜﻜﯩﺴﯩﻨﯩﯔ ﺋﺎﺭﯨﺴﯩﺪﯨﻜﻰ c2ﻧﯩﯔ ﻧﯩﻤﯩﺸﻘﺎ Customerﺗﯩﭗ ﺑﻮﻟﯘﭖ ﻗﺎﻟﻐﺎﻧﻠﯩﻘﯩـﺪﯨﻜﻰ ﺳﻪﯞﻩﺏ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﺎﻧﻨﯩﯔ) (编译器ﺟﯜﻣﻠﯩﻨﯩﯔ ﺑﺎﺵ -ﺋﺎﺧﯩﺮﯨﻐـﺎ ﺋﺎﺳﺎﺳـﻪﻥ ﺋﺎﭘﺘﻮﻣﺎﺗﯩـﻚ ﻛﻪﻟﺘـﯜﺭﯛﭖ ﭼﯩﻘﺎﺭﻏﺎﻧﻠﯩﻘﯩﺪﺍ c3,c4,c5,c6 .ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩﯔ ﺗﯩﭙﻰ ﺑﻮﻟﺴﺎ »ﻧﺎﻣﺴﯩﺰ ﺗﯩﭗ« ﻳﻪﻧﻰ ﺋﯘﻻﺭﻧﯩﯔ ﺗﯩﭗ ﻳﻮﻕ Customer) .ﻣﯩﻜﯩـﻦ ﺩﻩﭖ ﺋـﻮﻳﻼﭖ ﻗﺎﻟﻤـﺎﯓ( .ﺳـﻪﯞﻩﺑﻰ ﺋـﯘﻻﺭ ﺋﻮﺭﯗﻧﻼﺷـﻘﺎﻥ ﻗـﯘﺭﻻﺭﺩﺍ ﺋﯘﻻﺭﻧﯩـﯔ Customerﺋﯩﻜﻪﻧﻠﯧﻜﯩﻨﻰ ﺑﯩﻠﮕﯩﻠﻰ ﺑﻮﻟﯩﺪﯨﻐﺎﻥ ﻳﯧﺘﻪﺭﻟﯩﻚ ﺋﺎﺳﺎﺱ ﻳﻮﻕ. ﺋﻪﻣﯩــﺴﻪ ﺑــﯘ ﻧﺎﻣــﺴﯩﺰ ﺗﯩﭙﻠﯩــﻖ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩــﯔ ﺧﺎﺳــﻠﯩﻘﻠﯩﺮﯨﻨﯩﯔ ﺋﯩــﺴﯩﻤﻠﯩﺮﻯ ﻗﺎﻳــﺴﻰ؟ ﺋﯘﻻﺭﻧﯩــﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﺮﯨﭽﯘ؟ ﺋﯘﻻﺭﻧﻰ ﻗﺎﻧﺪﺍﻕ ﺯﯨﻴﺎﺭﻩﺕ ﻗﯩﻠﯩﻤﯩﺰ؟
ﺋﻮﺑﻴﯧﻜﯩﺖ
c3
ﺧﺎﺳـــﻠﯩﻖ ﻧﺎﻣﯩﻨﯩـــﯔ
ﺧﺎﺳﻠﯩﻘﻠﯩﺮﻯ
ﻛﯧﻠﯩﺶ ﻣﻪﻧﺒﻪﺳﻰ
ﺧﺎﺳﻠﯩﻖ ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻯ
Nameﺑﯩﻠﻪﻥ Age
ﺋﯚﺯﯨﻤﯩﺰ ﺑﻪﺭﮔﻪﻥ
Nameﺑﯩﻠﻪﻥ Age
c2ﺩﯨـــــــــــــــﻦ c2ﻧﯩـــﯔ ﻣﯘﻧﺎﺳـــﯩﭗ
ﺗﻪﻗﻠﯩﺪﻟﯩﯟﺍﻟﺪﻯ
c4
" "Tomﺑﯩﻠﻪﻥ 31 ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻯ ﺑﯩـﻠﻪﻥ
ﺧﺎﺳــﻠﯩﻖ ﻗﯩﻤﻤﯩﺘﯩﻨﯩــﯔ ﻣﻪﻧﺒﻪﺳﻰ
ﺋﯚﺯﯨﻤﯩﺰ ﺑﻪﺭﮔﻪﻥ c2
ﺋﻮﺧﺸﺎﺵ Nameﺑﯩﻠﻪﻥ Contry
c1ﺩﯨـــــــــــــــــــﻦ 1cﻧﯩـــﯔ ﻣﯘﻧﺎﺳـــﯩﭗ ﺗﻪﻗﻠﯩﺪﻟﯩﯟﺍﻟﺪﻯ
c5
ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻯ ﺑﯩـﻠﻪﻥ
c1
ﺋﻮﺧﺸﺎﺵ Contryﺑﯩﻠﻪﻥ Name
c6
c1ﺩﯨـــــــــــــــــﻦ c1ﻧﯩــﯔ ﻣﯘﻧﺎﺳــﯩﭗ ﺗﻪﻗﻠﯩﺪﻟﯩﯟﺍﻟﺪﻯ
ﻗﯩﻤﻤﻪﺗﻠﯩـــــــــﺮﻯ
c1
ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ ﺋﻪﮔﻪﺭ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﭘﺮﮔﺮﺍﻣﻤﺎ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﯘ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩﯔ ﺗﯩﭙﯩﻨـﻰ ﻛﯚﺭﺳﻪﺗـﺴﻪﻙ ﻧﻪﺗﯩـﺠﻪ ﺋﺎﺳـﺘﯩﺪﯨﻜﻰ ﺭﻩﺳﯩﻤﺪﻩ ﻛﯚﺭﺳﯩﺘﯩﻠﮕﻪﻧﺪﻩﻙ ﺑﻮﻟﯩﺪﯗ.
Console.WriteLine( "c1 is {0}", c1.GetType() ); Console.WriteLine( "c2 is {0}", c2.GetType() ); Console.WriteLine( "c3 is {0}", c3.GetType() ); Console.WriteLine( "c4 is {0}", c4.GetType() ); Console.WriteLine( "c5 is {0}", c5.GetType() ); ;)Console.WriteLine( "c6 is {0}", c6.GetType()
33
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺩﯦﻤﻪﻙ ﻣﯘﻧﺪﺍﻕ ﻳﻪﻛﯜﻧﮕﻪ ﺋﯧﺮﯨﺸﻪﻟﻪﻳﻤﯩﺰ: ﺑﯘﻻﺭﻧﯩﯔ ﺋﺎﺭﯨﺴﯩﺪﻛﻰ c1ﺑﯩﻠﻪﻥ c2ﺑﯩﺮﺩﻩﻙ Customerﺗﯩﭙﻠﯩـﻖ؛ c2ﺑﯩـﻠﻪﻥ c3ﮬﻪﺭ ﺋﯩﻜﻜﯩﻠﯩـﺴﻰ ﺑﯩﺮ ﻧﺎﻣﺴﯩﺰ ﺗﯩﭙﻨﯩـﯔ ﺋـﻮﺑﻴﯧﻜﯩﺘﻠﯩﺮﻯ .ﭼـﯜﻧﻜﻰ ﺋـﯘﻻﺭ ﺋﯜﭼـﯜﻥ ﺑﯧـﺮﯨﻠﮕﻪﻥ ﺧﺎﺳـﻠﯩﻖ ﻧـﺎﻣﻠﯩﺮﻯ ﺋﻮﭘﻤـﯘ- ﺋﻮﺧﺸﺎﺵ ،ﺷﯘﯕﺎ ﺋـﺎﻳﺮﯨﻢ ﺗﯩـﭗ ﻗﯘﺭﯗﺷـﻨﯩﯔ ﮬـﺎﺟﯩﺘﻰ ﻳـﻮﻕ.؛ ﮔﻪﺭﭼﻪ c5ﺑﯩـﻠﻪﻥ c6ﻧﯩـﯔ ﺧﺎﺳـﻠﯩﻖ ﻧﺎﻣﻠﯩﺮﯨﻨﻰ ﺋﻮﺧﺸﺎﺵ ﺑﻮﻟﺴﯩﻤﯘ ﭘﺎﺗﺎﻣﯧﺘﯩﺮﺩﻛﻰ ﺗﻪﺭﺗﯩﭙﻰ ﺋﻮﺧﺸﯩﻤﺎﻳﺪﯗ ،ﺷﯘﯕﺎ ﺋﯘﻻﺭ ﺋﯜﭼﯜﻥ ﺋﺎﻳﺮﯨﻢ ﺗﯩـﭗ ﻗﯘﺭﯗﻟﻐﺎﻥ. »ﻧﺎﻣـــﺴﯩﺰ ﺗﯩـــﭗ«ﺋﻮﺑﻴﯧﻜﯩﺘﻠﯩﺮﻧﯩـــﯔ ﺧﺎﺳـــﻠﯩﻘﻠﯩﺮﯨﻨﻰ obj.propertyﺷـــﻪﻛﻠﻰ ﺋـــﺎﺭﻗﯩﻠﯩﻖ ﺯﯨﻴـــﺎﺭﻩﺕ ﻗﯩﻼﻻﻳﺴﯩﺰ ،ﻳﻪﻧﻰstring str = c4.Name; :
Queryﺋﯩﭙﺎﺩﯨﺴﻰ )ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ( C#3.0ﺗﻪﻣﯩــﻨﻠﯩﮕﻪﻥ ﻳﻪﻧﻪ ﺑﯩــﺮ ﻣــﯘﮬﯩﻢ ﺋﯩﻘﺘﯩــﺪﺍﺭ ﺷــﯘﻛﻰ ،ﮔﺮﺍﻣﻤﺎﺗﯩﻜــﺎ ﺟﻪﮬﻪﺗــﺘﻪ Sqlﺟﯜﻣﻠﯩــﺴﯩﮕﻪ ﺋﻮﺧﺸﯩﺸﯩﭗ ﻛﯧﺘﯩﺪﯨﻐﺎﻥ ﺟﯜﻣﻠﯩﻠﻪﺭ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺳﺎﻥ -ﺳﯩﻔﯩﺮ ﻣﻪﺷﻐﯘﻻﺗﻰ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﺶ .ﺑﯘ ﮔﺮﺍﻣﻤﺎﺗﯩﻜـﺎ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻳﯧﺰﯨﻠﻐﺎﻥ ﺟﯜﻣﻠﯩﻠﻪﺭ Linqﺗﻪﻣﯩـﻨﻠﯩﮕﻪﻥ ﻣﯘﻧﺎﺳـﯩﯟﻩﺗﻠﯩﻚ ﺗـﯜﺭ ،ﺋﯧﻐﯩـﺰ ﯞﻩ ﻣﯩـﺰﻭﺗﻼﺭ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﯓ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﺪﺍ C#3.0ﻧﯩﯔ ﺋﯚﻟﭽﻪﻣﻠﯩﻚ ﺟﯜﻣﻠﯩﻠﯩﺮﯨﮕﻪ ﺋﺎﻳﻼﻧﺪﯗﺭﯗﻟﯩﺪﯗ. Queryﺋﯩﭙﺎﺩﯨﺴﻰ ﺗﻮﻏﯘﺭﻟﯩﻖ ﮬـﺎﺯﯨﺮ ﻛـﯚﭖ ﺗﻮﺧﺘﯩﻠﯩﻠﻤﺎﻳـﺪﯗ .ﺑـﯘ ﺋﯩﭙـﺎﺩﯨﮕﻪ ﺋﺎﺋﯩـﺖ ﻛـﯚﭘﺮﻩﻙ ﻣﻪﺯﻣـﯘﻧﻼﺭ Linqﻏﺎ ﺋﺎﻻﻗﯩﺪﺍﺭ ﻣﻪﺯﻣﯘﻧﻼﺭﺩﺍ ﺳـﯚﺯﻟﯩﻨﯩﺪﯗ .ﮬـﺎﺯﯨﺮ ﭘﻪﻗﻪﺕ ﺗﯩﭙﯩـﻚ ﺑﻮﻟﻐـﺎﻥ ﺋﯩﺸﻠﯩﺘﯩﻠﯩـﺸﻰ ﯞﻩ ﺋﯘﻧﯩـﯔ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﺪﺍ ﻗﺎﻧﺪﺍﻕ ﻗﯩﻠﯩﭗ Linqﺗﯩﭗ ﻣﯧﺘﻮﺩﻟﯩﺮﯨﻐﺎ ﺋﺎﻳﻠﯩﻨﯩﺪﯨﻐﺎﻧﻠﯩﻘﻰ ﺋﺎﺩﺩﻯ ﭼﯜﺷﻪﻧﺪﯛﺭﯛﻟﯩﺪﯗ. ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻛﻮﺩﻧﻰ Queryﺋﯩﭙﺎﺩﯨﺴﯩﻨﯩﯔ ﺗﯩﭙﯩﻚ ﻣﯩﺴﺎﻟﻰ ﺩﯦﻴﯩﺸﻜﻪﻥ ﺑﻮﻟﯩﺪﯗ:
var customers = new []{ new { Name = "Marco", Discount = 4.5 }, new { Name = "Paolo", Discount = 3.0 }, new { Name = "Tom", Discount = 3.5 } }; var query = from c in customers
34
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
where c.Discount > 3 orderby c.Discount select new { c.Name, Perc = c.Discount / 100 }; foreach( var x in query ) { Console.WriteLine( x ); } ﮬﻪﺭﺑﯩﺮ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ fromﺧﺎﺱ ﺳﯚﺯﯨﺪﯨﻦ ﺑﺎﺷﻠﯩﻨﯩﭗ)ﭼﻮﯓ -ﻛﯩﭽﯩﻚ ﮬﻪﺭﭘﻜﻪ ﺳﻪﺯﮔﯜﺭ( ﻳﺎ selectﻳﺎ groupﺧﺎﺱ ﺳـﯚﺯﻯ ﺑﯩـﻠﻪﻥ ﺋﺎﺧﯩﺮﻟﯩـﺸﯩﺪﯗ from .ﺧـﺎﺱ ﺳـﯚﺯﻯ Linqﻣﻪﺷـﻐﯘﻻﺗﻰ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﻤﺎﻗﭽﻰ ﺑﻮﻟﻐﺎﻥ ﮬﻪﻣﺪﻩ > IEnumerable IEnumerable
{ Name = Tom, Perc = 0.035 } }{ Name = Marco, Perc = 0.045 C# 3.0ﻳﯘﻗﯩﺮﯨﻘﻰ Queryﺋﯩﭙﺎﺩﯨﺴﯩﻨﻰ ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﻪ ﻣﻪﺯﮔﯩﻠﯩﺪﻩ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻳﯧﺰﯨﻠﻐﺎﻥ ﺑﺎﺭﺍﯞﻩﺭ ﮬﺎﻟﻪﺗﺘﻪ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯨﺪﯗ:
var query = customers .Where( c => c.Discount > 3) .OrderBy( c => c.Discount ) .Select( c=> new { c.Name, Perc = c.Discount / 100 } ); ﮬﻪﺭﺑﯩﺮ ﺋﯩﭙﺎﺩﻩ ﺧﺎﺱ ﺳﯚﺯﻯ)ﻣﻪﺳﯩﻠﻪﻥ (select :ﻣﻪﻟﯘﻡ ﻛﯚﭘﻤﺎﺱ ﻣﯧﺘﻮﺩﻗﺎ) (generic methodﺑﺎﺭﺍﯞﻩﺭ. ﺑﯘﻻﺭﺩﯨﻦ ﺷﯘﻧﻰ ﮬﯧﺲ ﻗﯩﻼﻻﻳﻤﯩﺰﻛﻰ ،ﺑﯩﺰ ﻳﯘﻗﯩﺮﯨﺪﺍ ﺳﯚﺯﻟﯩﮕﻪﻥ ﺑﺎﺭﻟﯩﻖ ﻳﯧﯖﻰ ﻗﺎﺋﯩﺪﯨﻠﻪﺭ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﺪﺍ Linqﻏﺎ ﺑﯧﺮﯨﭗ ﺗﺎﻗﯩﺸﯩﺪﯗ .ﻳﻪﻧﻰ varﺑﻮﻟﺴﺎ queryﻧﻪﺗﯩﺠﯩـﺴﯩﻨﻰ ﺋﯧﻨﯩﻘﻼﺷـﻘﺎ ،ﻧﺎﻣـﺴﯩﺰ ﺗﯩـﭗ ﺑﻮﻟـﺴﺎ queryﻧﻪﺗﯩﺠﯩــــﺴﯩﻨﻰ ﺳﺎﻗﻼﺷــــﻘﺎ from ،Select .ﻣﻪﺷــــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺑﻮﻟــــﺴﺎ ﻣﯘﻧﺎﺳــــﯩﭗ Linq ﻣﯩﺰﻭﺗﻠﯩﺮﯨﻨﯩﯔ ﺋﻮﺭﻧﯩﻐﺎ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ.
35
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
ﺗﯚﺗﯩﻨﭽﻰ ﺑﺎﺏ
www.udmish.cn
Linqﮔﺮﺍﻣﻤﺎﺗﯩﻜﯧﺴﯩﺪﯨﻦ ﺋﺎﺳﺎﺱ
ﺯﺍﻣﺎﻧﯩﯟﻯ ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﺗﯩﻠﻰ ﯞﻩ ﻳﯘﻣﺸﺎﻕ ﺩﯦﺘـﺎﻟﻼﺭ ﺋﺎﺳﺎﺳـﻪﻥ ﺩﯦﮕﯩـﺪﻩﻙ ﺋﻮﺑﻴﯧﻜﯩﺘﻘـﺎ ﻳـﯜﺯﻟﻪﻧﮕﻪﻥ ﻗﯘﺭﯗﻟﻤـﺎ ﺗﻪﺭﻩﭘـﺪﺍﺭﻯ ﺑﻮﻟﯘﯞﺍﺗﯩــﺪﯗ .ﻧﻪﺗﯩﺠﯩــﺪﻩ ﺑﯩﺰﻧﯩــﯔ ﻛــﯚﭖ ﻗﯩــﺴﯩﻢ ﻣﻪﺷــﻐﯘﻻﺗﻠﯩﺮﯨﻤﯩﺰ ﺟﻪﺩﯞﻩﻝ ﯞﻩ ﺭﯦﻜــﻮﺭﺗﻼﺭ ﺑﯩﻠﻪﻥ ﺋﻪﻣﻪﺱ ﺑﻪﻟﻜﻰ ﺋﻮﺑﻴﯧﻜﯩﺖ ﺗﻮﭘﻼﻣﻠﯩﺮﻯ ﯞﻩ ﺋﯘﻻﺭﻧﯩﯔ ﺋﻪﺯﺍﻟﯩﺮﻯ ﺑﯩﻠﻪﻥ ﮬﻪﭘﯩﻠﯩﺸﯩﺶ ﺑﻮﻟﯩﯟﺍﺗﯩـﺪﯗ. ﺷــﯘ ﺳــﻪﯞﻩﺑﻠﯩﻚ ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ ﺗﯩﻠﻠﯩــﺮﻯ ﺋﺎﻣــﺎﻝ ﺑــﺎﺭ ﻣــﯘﻗﯩﻢ ﺳــﺎﻥ ﻣﻪﻧﺒﻪﻟﯩﺮﯨﻨــﻰ)ﻣﻪﺳــﯩﻠﻪﻥ :ﺳــﺎﻧﺪﺍﻥ( ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﯨــﺪﯨﻦ ﺋــﺎﻳﺮﯨﺶ ﻳــﻮﻟﻠﯩﺮﻯ ﺋﯜﺳــﺘﯩﺪﻩ ﺋﯩﺰﺩﯨﻨﯩﯟﺍﺗﯩــﺪﯗ .ﺗﯩﻠﻐــﺎ ﺋﻮﺭﻧﯩﺘﯩﻠﻐــﺎﻥ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ) (Language Integrated Queryﻳﻪﻧــﻰ ﺋﺎﺗــﺎﻟﻤﯩﺶ Linqﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﻻﺭﻧــﻰ ﺗﺎﺭﻣــﺎﻗﭽﯩﻼﺭ ﺗﯩﺰﻣﯩــﺴﻰ )ﻳﻪﻧــﻰ ﺋــﻮﺑﻴﯧﻜﯩﺘﻼﺭ ،objectsﮔﻪﯞﺩﯨــﻠﻪﺭ ،entitiesﺳــﺎﻧﺪﺍﻥ ﺭﯦﻜــﻮﺭﺗﻠﯩﺮﻯ records
،database
XMLﻧــﯘﺧﺘﯩﻠﯩﺮﻯ ﻗﺎﺗــﺎﺭﻟﯩﻘﻼﺭ( ﻏــﺎ ﻧﯩــﺴﺒﻪﺗﻪﻥ ﺋﯜﻧﯜﻣﻠــﯜﻙ ﻣﻪﺷــﻐﯘﻻﺕ ﻗﯩﻠﯩــﺶ ﭼﺎﺭﯨــﺴﻰ ﺑﯩــﻠﻪﻥ ﺗﻪﻣﯩﻨﻠﻪﻳــﺪﯗ .ﺋﯘﻧﯩــﯔ ﺋﻪﯓ ﺋﯘﺗﯘﻗﻠــﯘﻕ ﻳﯧــﺮﻯ ﺷــﯘﻛﻰ ﺋــﯘ ﺗﯩﺰﻣﯩﻼﺭﻏــﺎ )ﺳــﺎﻧﺪﺍﻧﻤﯘ ﺷــﯘ( ﻻﺭﻏــﺎ ﺑﻮﻟﻐــﺎﻥ ﻣﻪﺷــﻐﯘﻻﺗﯩﯖﯩﺰﻧﻰ ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ ﺗﯩﻠــﻰ ﺑﯩــﻠﻪﻥ ﻳﯜﻛــﺴﻪﻙ ﺩﻩﺭﯨﺠﯩــﺪﻩ ﻳﯧﻘﯩﻨﻼﺷــﺘﯘﺭﻏﺎﻥ ﺑﻮﻟــﯘﭖ ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ ﺗﯩﻠﯩﻨﯩﯔ ﺋﺎﺩﺩﻯ ﻗﺎﺋﯩﺪﯨﻠﯩﺮﻯ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻣﯘﺭﻩﻛﻜﻪﭖ ﻣﻪﺷﻐﯘﻻﺗﻼﺭﻧﻰ)ﻣﻪﺳﯩﻠﻪﻥ ﺳـﺎﻧﺪﺍﻥ ﻣﻪﺷـﻐﯘﻻﺗﻠﯩﺮﻯ( ﺋﯩﻠﯩﭗ ﺑﺎﺭﺍﻻﻳﺴﯩﺰ.
LINQﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻠﯩﺮﻯ )(LINQ Queries LINQﺑﯩـــﺮ ﻗﯩـــﺴﯩﻢ ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﺋﻪﻣﻪﻟﻠﯩﺮﯨﻨـــﻰ ﺋﺎﺳـــﺎﺱ ﻗﯩﻠﯩـــﺪﯨﻐﺎﻥ ﺑﻮﻟـــﯘﭖ ،ﺋﺎﺳﺎﺳـــﻠﯩﻘﻰ > IEnumerable
ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﺴﻰ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﻨﻰ ﺳﯚﺯﻟﻪﺷﺘﯩﻦ ﺑﯘﺭﯗﻥ ﮔﻪﭘﻨﻰ ﺋﺎﺩﺩﻯ ﻣﯩﺴﺎﻝ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﺎﺷﻼﻱ .ﺗﯚﯞﻩﻧﺪﯨﻜﻪﻥ ﺗﯜﺭ ﺑﺎﺭ ﺩﻩﭖ ﭘﻪﺭﻩﺯ ﻗﯩﻼﻳﻠﻰ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮ ﺗﯜﺭﻯ//
{public class Developer public string Name; public string Language; public int Age; }
36
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻳﯘﻗﺎﺭﻗﻰ ﺗﯜﺭ ﺗﯩﭙﯩﻨﯩﯔ ﺗﻮﭘﻠﯩﻤﯩﻐﺎ ﻣﻪﺷﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﺎﺭﻣﺎﻗﭽﻰ ﺑﻮﻟﯘﯓ Linq To Objects .ﺋﺎﺭﻗﯩﻠﯩﻖ ﻣﻪﺯﻛﯘﺭ ﺗﻮﭘﺘﯩﻜﻰ C#ﺗﯩﻠﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﺪﯨﻐﺎﻥ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﻻﺭﻧﯩﯔ ﻧﺎﻣﯩﻨﻰ ﺑﯧﺴﯩﭗ ﭼﯩﻘﯩﺮﯨﺶ ﺋﯜﭼﯜﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛﻮﺩ ﻳﯧﺰﯨﻠﯩﺸﻰ ﻣﯘﻣﻜﯩﻦ ﻛﻮﺩ 4.1
using System; using System.Linq; using System.Collections.Generic; class app { static void Main() { Developer[] developers = new Developer[] { new Developer {Name = "Paolo", Language = "C#"}, new Developer {Name = "Marco", Language = "C#"}, new Developer {Name = "Frank", Language = "VB.NET"}}; IEnumerable<string> developersUsingCsharp = from d in developers where d.Language == "C#" select d.Name; foreach (string item in developersUsingCsharp) { Console.WriteLine(item); } } } ﻣﻪﺯﻛﯘﺭ ﻛﻮﺩ ﺳﯜﺯﯛﭖ ﭼﯩﻘﻘﺎﻥ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﻻﺭ Paoloﺑﯩﻠﻪﻥ .Marco ﻳﯘﻗﯩﺮﯨﻘﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺟﯜﻣﻠﯩﻠﯩﺮﻯ ﻗﺎﺭﯨﻤﺎﻗﻘﺎ Sqlﺟﯜﻣﻠﯩﺴﯩﮕﻪ ﺋﯩﻨﺘﺎﻳﯩﻦ ﺋﻮﺧﺸﯩﺸﯩﭗ ﻛﯧﺘﯩـﺪﯗ .ﺑﯩـﺮﺍﻕ ﺋﻪﻣﻪﺱ .ﺋﯘﻧﯩﯖﻐﺎ ﻣﯘﻧﺪﺍﻕ ﺋﯧﻨﯩﻘﻠﯩﻤﺎ ﺑﯧﺮﯨﻠﮕﻪﻥ: ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺑﻮﻟﺴﺎ ﺑﯩﺮ ﺧﯩـﻞ ﺩﻩﺭﻩﺧـﺴﯩﻤﺎﻥ ﺋﯩﭙـﺎﺩﻩ ﺑﻮﻟـﯘﭖ ﺑﯩـﺮ ﻳـﺎﻛﻰ ﺑﯩﺮﻗـﺎﻧﭽﻪ ﺋﯘﭼـﯘﺭ ﻣﻪﻧﺒﻪﺳﯩﮕﻪ ﺑﯩﺮ ﻳﺎﻛﻰ ﺑﯩﺮﻗﺎﻧﭽﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﻪﻣﯩﻠﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻣﻪﺷﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﺎﺭﯨﺪﯗ. ﺋﺎﺩﻩﺗﺘﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﻧﻪﺗﯩﺠﯩﺴﻰ ﺑﯩﺮ ﺗﻮﭘﻼﻡ ﻗﯩﻤﻤﻪﺗـﻠﻪﺭ ﺗﯩﺰﻣﯩـﺴﯩﺪﯨﻦ ﺋﯩﺒـﺎﺭﻩﺕ ﺑﻮﻟـﯘﭖ ﻗﯩﻤﻤﻪﺗـﻠﻪﺭﮔﻪ ﭼﯧﻘﯩﻠﯩﺶ ﻳﯜﺯ ﺑﻪﮔﻪﻧﺪﯨﻼ ﺋﺎﻧﺪﯨﻦ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﮬﻪﻗﯩﻘﻰ ﺋﯩﺠﺮﺍ ﺑﻮﻟﯩﺪﯗ. ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ selectﻳﻪﻧﻰ ﺗﺎﻟﻼﺵ ﻛﻮﻣﺎﻧﺪﯨﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﯧﻜﯩﺘﯩﻠﯩـﭗ )(select d.Name fromﻛﻮﻣﺎﻧﺪﯨﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺗﻮﭘﻼﻣﻐـﺎ ﺋﻪﻣﻪﻟﯩﻠﻪﺷـﺘﯜﺭﯛﻟﯩﺪﯗ ) .(from d as developersﺑـﯘ ﺗـﺎﻟﻼﺵ ﻣﻪﺷﻐﯘﻻﺗﯩﻨﻰ whereﻏﺎ ﻳﺎﻧﺪﺍﺷﻘﺎﻥ ﺳﯜﺯﯛﺵ ﺷﻪﺭﺗﯩﮕﻪ ﺑﻮﻱ ﺳﯘﻧﯩﺪﯗ .ﻳﻪﻧﻰ
"where d.Language == "C#
37
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﻛﻮﺩ-ﺗﻪﺭﺟﯩـﻤﻪ ﻗﯩﻠﯩـﺶ ﻣﻪﺯﮔﯩﻠﯩـﺪﻩ whereﺋﯩﭙﺎﺩﯨـﺴﻰ System.Linqﻧـﺎﻡ ﺑﻮﺷـﻠﯩﻘﯩﺪﺍ ﺋﯧﻨﯩﻘﻼﻧﻐﺎﻥ Enumerableﺗﯜﺭﯨﻨﯩﯔ ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩﻯ Whereﻏﺎ ﺋﯚﺯﻟﻪﺷﺘﯜﺭﯛﻟﯩﺪﯗ. System.Linqﻧـــﺎﻡ ﺑﻮﺷـــﻠﯩﻘﯩﺪﺍ > IEnumerable
IEnumerable<string> expr = developers .Where(d => d.Language == "C#") .Select(d => d.Name); ﺑﯘﻧﯩﯖــﺪﯨﻜﻰ Whereﻣﯧﺘــﻮﺩﻯ ﺑﯩــﻠﻪﻥ Selectﻣﯧﺘﻮﺩﯨﻨﯩــﯔ ﮬﻪﺭ ﺋﯩﻜﻜﯩﻠﯩــﺴﻰ Lambdaﺋﯩﭙﺎﺩﯨــﺴﯩﻨﻰ ﺋــﯚﺯﯨﮕﻪ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮ ﻗﯩﻠﯩــﺪﯗ ] ﻣﻪﺳــﯩﻠﻪﻥ .[ (d => d.Language == "C#") :ﺑــﯘ Lambda ﺋﯩﭙــﺎﺩﯨﻠﯩﺮﻯ ﺋﺎﺧﯩﺮﯨــﺪﺍ System.Linqﻧــﺎﻡ ﺑﻮﺷــﻠﯘﻗﯩﺪﺍ ﺋﺎﻟــﺪﯨﻦ ﺑﻪﻟﮕﯩﻠﻪﻧــﮕﻪﻥ ﻛﯚﭘﻤــﺎﺱ ﻣــﯘﯞﻩﻗﻘﻪﺕ ﺗﯩﭙﻠﯩﺮﯨﻐﺎ ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﯩﻨﯩﺪﯗ .ﺗﯚﯞﻩﻧـﺪﯨﻜﯩﻠﯩﺮﻯ ﺑﯧﻜﯩـﺘﻠﮕﻪﻥ ﻛﯚﭘﻤـﺎﺱ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﺗﯩﭙﻠﯩﺮﻧﯩـﯔ ﺗﻮﻟـﯘﻕ ﺗﻮﭘﻠﯩﻤﻰ:
public delegate T Func< T >(); public delegate T Func< A0, T >( A0 arg0 ); public delegate T Func< A0, A1, T > ( A0 arg0, A1 arg1 ); public delegate T Func< A0, A1, A2, T >( A0 arg0, A1 arg1, A2 arg2 ); public delegate T Func< A0, A1, A3, T > ( A0 arg0, A1 arg1, A2 arg2, ;)A3 arg3 Enumerableﺗﯜﺭﻧﯩﯔ ﻛﯚﭖ ﻗﯩـﺴﯩﻢ ﻛـﯧﯖﻪﺗﻤﻪ ﻣﯧﺘـﻮﺩﻟﯩﺮﻯ ﻳـﯘﻗﯩﺮﯨﻘﻰ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﺗﯩﭙﻼﺭﻧـﻰ ﭘـﺎﺭﺍﻣﯧﺘﯩﺮ ﺳــﯜﭘﯩﺘﯩﺪﻩ ﻗﻮﺑــﯘﻝ ﻗﯩﻼﻻﻳــﺪﯗ .ﻣﻪﺳــﯩﻠﻪﻥ :ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﻛﻮﺩﺩﯨﻜﯩــﺪﻩﻙ ﻗــﻮﻟﻠﯩﻨﯩﺶ ﻳــﯘﻗﯩﺮﯨﻘﻰ ﺑــﺎﺭﻟﯩﻖ ﺋﯩﭙﺎﺩﯨﻠﻪﺭﻧﯩﯔ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﻘﻰ ﺋﯚﺯﻟﻪﺷﺘﯜﺭﯛﻟﻤﯩﺴﯩﺪﯗﺭ. ﻛﻮﺩ 4.2
Func filteringPredicate = d => d.Language == "C#"; Func selectionPredicate = d => d.Name; IEnumerable<string> expr = developers .Where(filteringPredicate) .Select(selectionPredicate); C#3.0ﻛﻮﺩ-ﺗﻪﺭﺟﯩﻤﺎﻧﻰ ﻳﯘﻗﯩﺮﯨﻘﻰ ﮬﺎﻟﻪﺗﻜﻪ ﻗﺎﻧﺪﺍﻕ ﻛﻪﻟﺘﯜﺭﯛﺷﻨﻰ ﺑﯩﻠﯩﺪﯗ .ﺋﻪﻟﯟﻩﺗﺘﻪ ﺋﻪﮔﻪﺭ ﺳﯩﺰ Linq ﺑﯩﻠﯩﻤﻠﯩﺮﯨﻨﻰ ﭘﯩﺸﺸﯩﻖ ﺑﯩﻠﯩﭗ ﺑﻮﻟﻐﺎﻧﺪﯨﻦ ﻛﯧﻴﯩﻦ ﺑﯩﯟﺍﺳﺘﻪ ﻣﯘﺷﯘ ﺧﯩﻞ ﮔﯩﺮﺍﻣﺎﺗﯩﻜﯩﻨﻰ ﻗﻮﻟﻼﻧﺴﯩﯖﯩﺰﻣﯘ ﺑﻮﻟﯩﺪﯗ .ﻟﯧﻜﯩﻦ ﺗﻪﺷﻪﺑﺒﯘﺳﯘﻡ ﺷﯘﻛﻰ ﺯﯙﺭﯛﺭﯨﻴﻪﺕ ﺗﯘﻏﯘﻟﻤﯩﺴﯩﻼ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﯔ.
38
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺗﻮﻟﯘﻕ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺋﺎﻟــﺪﯨﻨﻘﻰ ﻣﻪﺯﻣــﯘﻧﻼﺭﺩﺍ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨــﺴﯩﻨﯩﯔ ﺋــﻮﺑﻴﯧﻜﯩﺘﻼﺭ ﺗــﻮﭘﻠﯩﻤﻰ ﺋﯜﺳــﺘﯩﺪﯨﻜﻰ ﺋــﺎﺩﺩﯨﻲ ﻣﻪﺷــﻐﯘﻻﺗﻠﯩﺮﯨﻨﻰ ﻛــﯚﺭﯛﭖ ﺋﯚﺗﺘــﯘﻕ .ﺗﻮﻟــﯘﻕ ﺑﻮﻟﻐــﺎﻥ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨــﺴﻰ ﺗﯧﺨﯩﻤــﯘ ﻣــﯘﻛﻪﻣﻤﻪﻝ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﻠﯩﻖ ﻗﯘﺭﯗﻟﻤﯩﻐﺎ ﺋﯩـﮕﻪ .ﮬﻪﺭﺑﯩـﺮ ﺋﯩﭙـﺎﺩﻩ fromﺩﯨـﻦ ﺑﺎﺷـﻠﯩﻨﯩﭗ ﻳـﺎ selectﻳـﺎ groupﺩﯨـﻦ ﺋﺎﺧﯩﺮﻟﯩﺸﯩﺪﯗ Sql .ﺟﯜﻣﻠﯩﺴﯩﮕﻪ ﺋﻮﺧﺸﺎﺵ selectﺩﯨﻦ ﺑﺎﺷﻠﯩﻨﯩﭗ fromﺩﯨـﻦ ﺋﺎﺧﯩﺮﻻﺷﻤﺎﺳـﻠﯩﻘﯩﺪﯨﻜﻰ ﺳﻪﯞﻩﺏ ﻛﻮﺩ ﻳﺎﺯﻏﺎﻧﺪﺍ ﻣﯩﻜﺮﻭﺳﻮﻓﺘﻨﯩﯔ »ﺋﻪﻗﻠﯩﻲ ﺗﻪﯞﺳﯩﻴﻪ«ﺋﯩﻘﺘﯩـﺪﺍﺭﻯ ﺑﯩـﻠﻪﻥ ﺗﻪﻣﯩﻨﻠﻪﺷـﻜﻪ ﻗﻮﻻﻳﻠﯩـﻖ ﻳـــﺎﺭﯨﺘﯩﺶ ﺋﯜﭼﯜﻧـــﺪﯗﺭ select .ﺧـــﺎﺱ ﺳـــﯚﺯﻯ ﺋﯩﭙـــﺎﺩﻩ ﻧﻪﺗﯩﺠﯩـــﺴﯩﻨﻰ enumerableﺋﻮﺑﻴﯧﻜﯩﺘﯩﻐـــﺎ ﺋﻮﺭﯗﻧﻼﺷﺘﯘﺭﯨﺪﯗ group .ﺧﺎﺱ ﺳﯚﺯﻯ ﺑﻮﻟـﺴﺎ ﺋﯩﭙـﺎﺩﻩ ﻧﻪﺗﯩﺠﯩـﺴﯩﻨﻰ ﮔـﯘﺭﯗﭘﯩﻼﺵ ﺷـﻪﺭﺗﯩﮕﻪ ﺋﺎﺳﺎﺳـﻪﻥ ﮬﻪﺭﺑﯩﺮ ﮔﯘﺭﯗﭘﭙﺎ enumerableﺑﻮﻟﻐﺎﻥ ﮔﯘﺭﯗﭘﭙﯩﻼﺭ ﺗﻮﭘﻠﯩﻤﯩﻐﺎ ﺑﯚﻟﯩﺪﯗ. ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﻨﯩﯔ ﺗﻮﻟﯘﻕ ﺑﻮﻟﻐﺎﻥ ﺋﻪﻧﺪﯨﺰﻩ)ﻗﯧﻠﯩﭗ( ﻛﻮﺩﻯ:
query‐expression ::= from‐clause query‐body query‐body ::= join‐clause* (from‐clause join‐clause* | let‐clause | where‐clause)* orderby‐clause? (select‐clause | groupby‐clause) query‐continuation? from‐clause ::= from itemName in srcExpr select‐clause ::= select selExpr groupby‐clause ::= group selExpr by keyExpr
ﺗﯘﻧﺠﻰ fromﺧﺎﺱ ﺳﯚﺯﻯ ﻛﻪﻳﻨﯩﮕﻪ ﻧﯚﻝ ﻳﺎﻛﻰ ﻧﻪﭼﭽﻪ ،let ،fromﻳﺎﻛﻰ whereﺧﺎﺱ ﺳـﯚﺯﻟﯩﺮﻯ ﺋﻪﮔﯩـــﺸﯩﭗ ﻛﯧﻠﻪﻟﻪﻳـــﺪﯗ let .ﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﻰ ﺋﯩﭙـــﺎﺩﻩ ﻧﻪﺗﯩﺠﯩـــﺴﯩﮕﻪ ﻧـــﺎﻡ ﺑﯧﺮﻩﻟﻪﻳـــﺪﯗfrom . ﻣﻪﺷﻐﯘﻻﺗﭽﯩــــﺴﯩﮕﻪ ﻛــــﯚﭖ ﺩﺍﻧﻪ joinﻣﻪﺷﻐﯘﻻﺗﭽﯩــــﺴﻰ ﺋﻪﮔﯩــــﺸﻪﻟﻪﻳﺪﯗ .ﺋﻪﯓ ﺋــــﺎﺧﯩﺮﯨﻘﻰ select ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯔ ﺋﺎﺧﯩﺮﯨﻐـﺎ orderbyﺧـﺎﺱ ﺳـﯚﺯﯨﻨﻰ ﺋﻪﮔﻪﺷـﺘﯜﺭﯛﺵ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﻧﻪﺗﯩﺠﯩﻨـﻰ ﻣﻪﻟـﯘﻡ ﺧﺎﺳﻠﯩﻘﻘﺎ ﺋﺎﺳﺎﺳﻪﻥ ﺳﻮﺭﺗﻠﯩﻐﯩﻠﻰ ﺑﻮﻟﯩﺪﯗ. ﺑﯘﻧﺪﯨﻦ ﻛﯧﻴﯩﻨﻜﻰ ﺋﯘﻗﯘﻣﻼﺭﻧﻰ ﭼﯜﺷﻪﻧﺪﯛﺭﯛﺷﻜﻪ ﻗﻮﻻﻳﻠﯩﻖ ﺑﻮﻟﯘﺵ ﺋﯜﭼﯜﻥ ﻣﯩﺴﺎﻟﻼﺭﻏﺎ ﺗﻮﻟﯘﻗﺮﺍﻕ ﺑﻮﻟﻐﺎﻥ ﺗﯜﺭ ﻗﯘﺭﯗﻟﻤﯩﺴﻨﻰ ﺗﯜﺯﯛﯞﯛﻻﻳﻠﻰ .ﺑﯩﺰ ﺑﯘﻧﺪﯨﻦ ﻛﯧﻴﯩﻦ ﺩﺍﺋﯩﻢ ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﺗﻮﭘﻠﯩﻤﯩﻐﺎ ﻣﻪﺷﯩﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﺎﺭﯨﻤﯩﺰ ) . (class Customerﮬﻪﺭﺑﯩﺮ ﺧﯧﺮﯨﺪﺍﻧﯩﯔ ﺑﯘﻳﺮﯗﺗﻘﺎﻥ ﻣﺎﻟﻠﯩﺮﻯ ﺑﺎﺭ .ﺋﯘﻻﺭﻧﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﺵ ﻛﻮﺩﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ:
www.udmish.cn
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
ﻣﯩﺴﺎﻟﻼﺭ ﺋﯜﭼﯜﻥ ﺗﯜﺭ ﻗﯘﺭﯗﻟﻤﯩﺴﻰ
public enum Countries { USA, Italy, } public class Customer { public string Name; public string City; public Countries Country; public Order[] Orders; } public class Order { public int Quantity; public bool Shipped; public string Month; public int IdProduct; } public class Product { public int IdProduct; public decimal Price; } // ------------------------------------------------------// ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﺗﻮﭘﻠﯩﻤﯩﻨﻰ ﺩﻩﺳﻠﻪﭘﻠﻪﺷﺘﯜﺭﯛﺵ // -------------------------------------------------------
customers = new Customer[] { new Customer {Name = "Paolo", City = "Brescia", Country = Countries.Italy, Orders = new Order[] { new Order {Quantity = 3, IdProduct = 1 , Shipped = false, Month = "January"}, new Order {Quantity = 5, IdProduct = 2 , Shipped = true, Month = "May"}}}, new Customer {Name = "Marco", City = "Torino", Country = Countries.Italy, Orders =
39
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
new Order[] { new Order {Quantity = 10, IdProduct = 1 , Shipped = false, Month = "July"}, new Order {Quantity = 20, IdProduct = 3 , Shipped = true, Month = "December"}}}, new Customer {Name = "James", City = "Dallas", Country = Countries.USA, Orders = new Order[] { new Order {Quantity = 20, IdProduct = 3 , Shipped = true, Month = "December"}}}, new Customer {Name = "Frank", City = "Seattle", Country = Countries.USA, Orders = new Order[] { new Order {Quantity = 20, IdProduct = 5 , Shipped = false, Month = "July"}}}}; products = new Product[] { new Product {IdProduct = 1, Price = 10 }, new Product {IdProduct = 2, Price = 20 }, new Product {IdProduct = 3, Price = 30 }, new Product {IdProduct = 4, Price = 40 }, new Product {IdProduct = 5, Price = 50 }, new Product {IdProduct = 6, Price = 60 }};
ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﻧـﺎﻡ ﺑﻮﻟـﺸﻠﯘﻗﯩﺪﺍ ﺗﻪﻣﯩـﻨﻠﻪﻧﮕﻪﻥ ﺋﺎﺳﺎﺳـﻠﯩﻖ ﻣﯧـﺰﻭﺩﻻﺭ ﯞﻩ ﻛﯚﭘﻤـﺎﺱSystem.Linq ﮬﺎﺯﯨﺮﺩﯨﻦ ﺑﺎﺷﻼﭖ ﺩﯨــﻦ ﭘﺎﻳــﺪﯨﻠﯩﻨﯩﭗ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﺋﯧﻠﯩــﭗLinq ﻣــﯘﯞﻩﻗﻘﻪﺕ ﺗﯩﭙﻠﯩﺮﯨﺮﯨﻨــﻰ ﭼﯜﺷــﻪﻧﺪﯛﺭﯛﺵ ﺋــﺎﺭﻗﯩﻠﯩﻖ .ﺑﯧﺮﯨﺶ ﺗﻮﻧﯘﺷﺘﯘﺭﯗﻟﯩﺪﯗ
ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰWhere )ﺋﯩﺘﺎﻟﯩﻴﻪ( ﺑﻮﻟﻐﺎﻥ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔItaly )ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﯩﺴﺎﻝ ﻛﻮﺩﻯ ﺋﺎﺳﺎﺳﯩﺪﺍ( ﺳﯩﺰﮔﻪ ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ ﺧﺎﺱwhere ﺑﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ ﺑﺎﺭﻟﯩﻖ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﻰ ﭼﺎﺭﻻﺵ ﺟﻪﺭﻳﺎﻧﯩﻐﺎ.ﻧﺎﻡ ﯞﻩ ﺷﻪﮬﻪﺭ ﺗﯩﺰﯨﻤﻠﯩﻜﻰ ﻻﺯﯨﻢ ﺳﯚﺯﻯ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻚ ﭼﻪﻛﻠﯩﻤﯩﺴﯩﻨﻰ ﺑﻪﺭﺳﯩﯖﯩﺰﻻ ﻛﯘﭘﺎﻳﻪ)ﺑﯘﺭﯗﻥ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺑﯘ ﻳﻪﺭﺩﯨﻜﻰ،ﺋﯩﭙﺎﺩﯨﺴﯩﺪﯨﻜﻰ ﺧﺎﺱ ﺳﯚﺯﻟﻪﺭﮔﻪ ﻣﯘﻧﺎﺳﯩﭗ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭﻧﯩﯔ ﺑﺎﺭﻟﯩﻘﯩﻨﻰ ﺋﻪﺳﻜﻪﺭﺗﻜﻪﻥ : ﻳﻪﻧﻰ. ( ﺧﺎﺱ ﺳﯚﺯﯨﮕﻪ ﻣﯘﻧﺎﺳﯩﭗ ﻛﯧﻠﯩﺪﯗwhere ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰWhere
40
41
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﻮﺩ 4.3
var expr = from c in customers where c.Country == Countries.Italy select new { c.Name, c.City };
ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ Whereﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ:
public static IEnumerable Where( this IEnumerable source, Func predicate); public static IEnumerable Where( this IEnumerable source, ;) Func predicate ﻗﯧﻠﯩﭗ ﻛﻮﺩﯨﺪﯨﻦ ﺷﯘﻧﻰ ﻛﯚﺭﯛﯞﯦﻠﯩﺸﻘﺎ ﺑﻮﻟﯩﺪﯗ Where ،ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯔ ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﺋﯩﻜﻜـﻰ ﺧﯩـﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﻰ ﺑﺎﺭ ﺑﻮﻟﯘﭖ ،ﺑﯩﺰ ﻳﯘﻗﯩﺮﯨﺪﺍ ﺋﯩﺸﻠﻪﺗﻜﯩﻨﻰ ﺑﯩﺮﯨﻨﭽﻰ ﺧﯩﻠﻰ .ﻳﻪﻧﻪ ﺑﯩﺮ ﺧﯩﻠﯩـﺪﺍ ﺑﻮﻟـﺴﺎ ﭘﯜﺗـﯜﻥ ﺳــﺎﻥ ﺗﯩﭙﻠﯩــﻖ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮ ﺑﯧﻜﯩﺘﻪﻟﻪﻳﻤﯩــﺰ .ﺋــﯘ ﻧــﯚﯞﻩﺗﺘﯩﻜﻰ ﺋﻮﺑﻴﯧﻜﯩﺘﻨﯩــﯔ ﺭﻩﺕ ﺗﻪﺭﺗﯩــﯟﯨﻨﻰ ﺑﯩﻠﺪﯛﺭﯨــﺪﯗ. ﻣﻪﺳﻠﻪﻥ: ﻛﻮﺩ 4.4
var expr = customers .Where((c, index) => (c.Country == Countries.Italy && index >= 1)) .Select(c => c.Name);
ﺑـﯘ ﺋﯩﭙـﺎﺩﻩ ﺗﻪﺭﺗﯩـﭗ ﻧﻮﻣـﯘﺭﻯ 0ﺑﻮﻟﻐـﺎﻥ ﺧﯧﺮﯨـﺪﺍﺭ )ﻳﻪﻧـﻰ Paoloﺋﯩـﺴﯩﻤﻠﯩﻚ ﺧﯧﺮﯨـﺪﺍﺭ( index>=1 ﺷﻪﺭﺗﯩﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﻣﯩﮕﻪﭼﻜﻪ ﻧﻪﺗﯩﺠﻪ ﺗﻮﭘﻠﯩﻤﯩﻐﺎ ﻛﯩﺮﻩﻟﻤﻪﻳﺪﯗ. ﺋﻪﭘﺴﯘﺳﻠﯩﻨﺎﺭﻟﯩﻖ ﻳﯧﺮﻯ ﺷﯘﻛﻰ ،ﺋﯩﻜﻜﯩﭽﻰ ﺧﯩﻞ ﺋﻪﻧـﺪﯨﺰﯨﻨﻰ ﺳﯜﺭﯛﺷـﺘﯜﺗﯜﻙ ﺋﯩﭙﺎﺩﺳـﯩﺪﻩ ﺋﯩﭙـﺎﺩﯨﻠﯩﮕﯩﻠﻰ ﺑﻮﻟﻤﺎﻳﺪﯗ ) … from….where….selectﺋﺎﺭﻗﯩﻠﯩﻖ ﺩﯦﻤﻪﻛﭽﻰ(. ﺷﯘﻧﯩﺴﻰ ﺋﯧﺴﯩﯖﯩﯩﺰﺩﻩ ﺗﯘﺭﺳﯘﻧﻜﻰ ،ﻧﻮﺭﻣﺎﻝ ﮬﺎﻟﻪﺗﺘﻪ ﺗﯘﺭﻏﯘﻥ ﻗﻪﯞﻩﺕ ) ،persistence layerﻣﻪﺳـﯩﻠﻪﻥ: ﺳﺎﻧﺪﺍﻥ( ﺩﯨﻦ ﻛﯚﭖ ﻣﯩﻘﺪﺍﺭﺩﯨﻜﻰ ﺋﯘﭼﯘﺭﻧﻰ ﺋﯩﭽﻜﻰ ﺳﺎﻗﻠﯩﻐﯘﭼﻘﺎ ﺋﻮﻗﯘﭖ ﻛﯩﺮﯨـﺸﻨﻰ ﻳﺎﺧـﺸﻰ ﻣﻪﺷـﻐﯘﻻﺕ ﺩﯦﮕﯩﻠﻰ ﺑﻮﻟﻤﺎﻳﺪﯗ .ﺋﺎﺩﻩﺗﺘﻪ ،ﺋﯘﭼﯘﺭﻻﺭﻧﻰ ﺗﯘﺭﻏﯘﻥ ﻗﻪﯞﻩﺕ ﺩﻩﺭﯨﺠﯩﺴﯩﺪﯨﻼ ﺑﻪﺗﻠﻪﺭﮔﻪ ﺑـﯚﻟﮕﻪﻥ)ﺷـﻪﺭﺗﻠﻪﺭ ﺋﺎﺭﻗﯩﻠﯩﻖ( ﻳﺎﺧﺸﻰ .ﮔﻪﺭﭼﻪ ﺑﯘ ﺧﯩﻞ ﺋﯘﺳﯘﻝ ﺑﺎﺭﻟﯩﻖ ﺋﯘﭼﯘﺭﻧﻰ ﺋﯩﭽﻜـﻰ ﺳـﺎﻗﻠﯩﻐﯘﭼﺘﺎ ﺗـﯘﺭﯗﭖ ﺑﻪﺗـﻠﻪﺭﮔﻪ ﺑﯚﻟﮕﻪﻧﮕﻪ ﻗﺎﺭﯨﻐﺎﻥ ﺋﺎﺳﺘﯩﺮﺍﻕ)ﻧﯩﺴﭙﻰ( ﺑﻮﻟﺴﯩﻤﯘ ،ﻳﻪﻧﯩﻼ ﭼﻮﻗﯘﻡ ﻛﯩﺮﯨﺶ ﺟﻪﺭﻳﺎﻧﯩﻐﺎ ﻛﻪﺗـﻜﻪﻥ ﯞﺍﻗﯩﺘـﺘﯩﻦ ﺋﯘﺗﺎﻻﻳﻤﯩﺰ.
42
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﻪﻣﻪﻟﯩﻠﻪﺷﺘﯜﺭﯛﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )(Projection Operators Selectﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺋﻪﻣﻪﻟﯩﻠﻪﺷــﺘﯜﺭﯛﺵ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﻣﻪﻧــﺒﻪﺩﯨﻦ ﺋﯘﭼــﯘﺭﻻﺭﻧﻰ ﺷــﻪﺭﺗﻜﻪ ﺋﺎﺳﺎﺳــﻪﻥ ﻳﯩﻐﯩــﭗ ﻧﻪﺗﯩﺠﯩــﮕﻪ ﺋﻮﺭﯗﻧﻼﺷﺘﯘﺭﯗﺵ ﺭﻭﻟﯩﻨﻰ ﺋﻮﻳﻨﺎﻳﺪﯗ .ﻳﯘﻗﯩﺮﯨﺪﺍ ﻛﯚﭖ ﺋﯘﭼﺮﺍﺗﻘﺎﻥ Selectﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺋﯘﻧﯩﯔ ﺗﯩﭙﯩﻚ ﻣﯩــﺴﺎﻟﻰ .ﺑﯘﻧــﺪﺍﻕ ﺩﯦﻴﯩــﺸﯩﻤﯩﺰﯨﺪﯨﻜﻰ ﺳــﻪﯞﻩﺏ ﺋــﯘ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﻧﻪﺗﯩﺠﯩــﺴﯩﻨﻰ >IEnumerable
public static IEnumerable<S> Select( this IEnumerable source, Func selector); public static IEnumerable<S> Select( this IEnumerable source, ;) Func selector ﺧﯘﺩﺩﻯ Whereﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻐﺎ ﺋﻮﺧﺸﺎ Selectﻣﻪﺷﺨﯘﻻﭼﯩﺴﯩﻤﯘ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﻨﻰ)ﺗﻮﭘﻼﻡ ﺋﻮﺑﻴﯧﻜﯩﺖ( ﭼﺎﺭﻻﻳﺪﯗ ﯞﻩ ﺷﻪﺭﺗﻜﻪ ﺋﯘﻳﻐﯘﻧﻠﯩﺮﯨﻨﻰ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩﺴﯩﻐﺎ)ﻧﻪﺗﯩﺠﻪ ﺗﻮﭘﻼﻡ ﺋﻮﺑﻴﯧﻜﯩﺘﻰ( ﺋﻮﺭﯗﻧﻼﺷﺘﯘﺭﯨﺪﯗ. ﻣﻪﺳﯩﻠﻪﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺟﯜﻣﻠﯩﮕﻪ ﻗﺎﺭﺍﯓ:
;)var expr = customers.Select(c => c.Name ﻣﻪﺯﻛــــــﯘﺭ ﺟﯜﻣﻠﯩﻨﯩــــــﯔ ﻧﻪﺗﯩﺠﯩــــــﺴﻰ ﺧﯧﺮﯨــــــﺪﺍﺭﻻﺭﻧﯩﯔ ﺋﯩــــــﺴﯩﻤﯩﻨﯩﯔ ﺗﯩﺰﻣﯩــــــﺴﻰ ﺑﻮﻟﯩــــــﺪﯗ )>.(IEnumerable<string ﺋﻪﻣﺪﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﯩﻨﻰ ﻛﯚﺭﯛﭖ ﺑﺎﻗﺎﻳﻠﻰ:
;)}var expr = customers.Select(c => new { c.Name, c.City ﺑﯘ ﺟﯜﻣﻠﯩﺪﯨﻦ ﻗﺎﻳﺘﯩـﺪﯨﻐﯩﻨﻰ Nameﯞﻩ Cityﺩﯨـﻦ ﺋﯩﺒـﺎﺭﻩﺕ ﺋﯩﻜﻜـﻰ ﺩﺍﻧﻪ ﺧﺎﺳـﻠﯩﻘﻰ ﺑﻮﻟﻐـﺎﻥ ﻧﺎﻣـﺴﯩﺰ ﺗﯩﭙﻠﯩﻖ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭ ﺗﯩﺰﻣﯩﺴﻰ ﺑﻮﻟﯘﭖ ،ﺋﯘ ﺧﺎﺳﻠﯩﻘﻠﯩﺮﻧﯩﯔ ﻗﯩﻤﻤﯩﺘـﻰ ﻣﻪﻧـﺒﻪ ﺧﯧﺮﯨـﺪﺍﺭﻻﺭ ﺗﯩﺰﻣﯩـﺴﯩﺪﯨﻜﻰ ) (customersﻳﻪﻛﻜﻪ ﺧﯧﺮﯨﺪﺍﺭ ﺋﻮﺑﻴﯧﻜﯩﺘﯩﺪﯨﻦ ﻛﯧﻠﯩﺪﯗ. Selectﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﯩﻨﯩﯔ ﺋﯩﻜﻜﯩﭽـــﻰ ﺧﯩـــﻞ ﺋﻪﻧﺪﯨﺰﯨﯩـــﺴﯩﺪﻩ ﭘﯜﺗـــﯜﻥ ﺳـــﺎﻥ ﺗﯩﭙﻠﯩـــﻖ ﭘـــﺎﺭﺍﻣﯧﺘﺮﻯ ﺋﯩﺸﻠﯩﺘﻪﻟﻪﻳﻤﯩﺰ .ﺑﯘ ﭘـﺎﺭﺍﻣﯧﺘﯩﺮ ﻣﻪﻧـﺒﻪ ﺋﻮﺑﻴﯧﻜﯩـﺖ ﺗﯩﺰﻣﯩـﺴﯩﺪﯨﻜﻰ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩـﯔ ﻧﯚﻟـﺪﯨﻦ ﺑﺎﺷـﻼﻧﻐﺎﻥ ﺗﻪﺭﺗﯩﭗ ﻧﻮﻣﯘﺭﯨﻨﻰ ﻛﯚﺭﺳﯩﺘﯩﺪﯗ.
43
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
SelectManyﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ Italyﺑﻮﻟﻐﺎﻥ ﺑﺎﺭﻟﯩﻖ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ﺑﺎﺭﻟﯩﻖ ﺯﺍﻛﺎﺯﻟﯩﺮﯨﻐﺎ ﺋﯧﺮﯨـﺸﻤﻪﻛﭽﻰ ﺑﻮﻟـﺴﯩﯖﯩﺰ. ﺑﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛﻮﺩ ﻳﯧﺰﻯ ﻳﯧﺰﯨﺸﯩﯖﯩﺰ ﻣﯘﻣﻜﯩﻦ: ﻛﻮﺩ 4.6
var orders = customers .Where(c => c.Country == Countries.Italy) .Select(c => c.Orders); foreach(var item in orders) { Console.WriteLine(item); } Selectﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﯩﻨﯩﯔ ﻧﻮﺭﻣـــﺎﻝ ﺧﯘﻟﻘﯩﻐـــﺎ ﺋﺎﺳﺎﺳـــﻪﻥ ﻣﻪﺯﻛـــﯘﺭ ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻛﻨﯩﯔ ﻧﻪﺗﯩﺠﯩـــﺴﻰ >][ IEnumerable
][DevLeap.Linq.Operators.Order ][DevLeap.Linq.Operators.Order ﺩﯦﻤﻪﻙ ﺑﯘ ﺑﯩﺰ ﻣﻪﻗﺴﻪﺕ ﻗﯩﻠﻐﺎﻥ > IEnumerable IEnumerable
public static IEnumerable<S> SelectMany( this IEnumerable source, Func> selector); public static IEnumerable<S> SelectMany( this IEnumerable source, Func> selector); public static IEnumerable<S> SelectMany( this IEnumerable source, Func> collectionSelector, Func resultSelector); ﻣﻪﺯﻛﯘﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﭼﺎﺭﻻﭖ ﻧﻪﺗﯩﺠﻪ ﺋﻪﺯﺍﻟﯧﺮﯨﻨﻰ) (itemsﺑﯩﺮﻟﻪﺷﺘﯜﺭﯨﺪﯗ ﯞﻩ ﺋـﯘﻻﺭﻧﻰ ﭼﺎﺭﻻﺷﻘﺎ ﺑﻮﻟﯩـﺪﯨﻐﺎﻥ)>IEnumerable
44
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﻮﺩ 4.7
IEnumerable orders = customers .Where(c => c.Country == Countries.Italy) .SelectMany(c => c.Orders); ﻛﻮﺩ 4.7ﺩﯨﻜﻰ ﺋﯩﭙﺎﺩﻩ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺑﯩﻠﻪﻥ ﺑﺎﺭﺍﯞﻩﺭ: ﻛﻮﺩ 4.8
IEnumerable orders = from c in customers where c.Country == Countries.Italy from o in c.Orders select o; ﻳﯘﻗﯩﺮﯨﻘﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﺪﯨﻜﻰ selectﺧـﺎﺱ ﺳـﯚﺯﻯ ﺗـﯘﻧﺠﻰ fromﺧـﺎﺱ ﺳـﯚﺯﯨﺪﯨﻦ ﺑﺎﺷـﻘﺎ fromﻻﺭ ﺑﯩــﻠﻪﻥ ﺑﯩﺮﻟﯩــﺸﯩﭗ SelectManyﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﯩﻐﺎ ﺗﻪﺭﺟﯩــﻤﻪ ﻗﯩﻠﯩﻨﯩــﺪﯗ .ﺑﺎﺷــﻘﯩﭽﻪ ﻗﯩﻠﯩــﭗ ﺋﯧﻴﺘﻘﺎﻧﺪﺍ ،ﺋﻪﮔﻪﺭ ﺋﯩﭙﺎﺩﯨﺪﻩ ﺑﯩﺮﺩﯨﻦ ﺋـﺎﺭﺗﯘﻕ fromﺧـﺎﺱ ﺳـﯚﺯﻯ ﺑﻮﻟـﺴﺎ ﻛـﺎﻟﻠﯩﯖﯩﺰﺩﺍ ﺗﯚﯞﻩﻧﺪﯨﻜﯩـﺪﻩﻙ ﻗﺎﺋﯩــﺪﯨﮕﻪ ﺳــﯧﻠﯩﯟﯦﻠﯩﯔ select :ﺑﯩــﻠﻪﻥ ﺗــﯘﻧﺠﻰ fromﻧﯩــﯔ ﺑﯩﺮﻟﯩﺸﯩــﺸﻰ Selectﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﯩﻐﺎ ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﯩﻨﯩﺪﯗ ،ﺑﺎﺷﻘﺎ ﺑﯩﺮﻟﯩﺸﯩﺸﻠﻪﺭ ﺑﯩﺮﺩﻩﻙ SelectManyﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻐﺎ ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﯩﻨﯩﺪﯗ. ﺋﯜﭼﯩﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﻨﻰ ﺗﻪﭘﺴﯩﻠﯩﻲ ﺳﯚﺯﻟﯩﻤﻪﻳﻤﻪﻥ .ﺋﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ ﺑﯩﺮ ﻣﯩﺴﺎﻝ ﻗﺎﻟﺪﯗﺭﺍﻱ: ﻛﻮﺩ 4.10
IEnumerable orders = from c in customers where c.Country == Countries.Italy from o in c.Orders select new {o.Quantity, o.IdProduct};
45
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
Orderingﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﺳﻮﺭﺗﻼﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ( Orderingﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﯨﻨﯩﯔ ﻗﻮﻟﻠﯩﻨﯩﺸﭽﺎﻧﻠﯩﻘﯩﻤﯘ ﺑﯩﺮﻗﻪﺩﻩﺭ ﻳﯘﻗﯩﺮﻯ ﺑﻮﻟﯘﭖ ،ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩـﺴﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﯩﯔ ﺗﻪﺭﺗﯩﭙﯩﻨﻰ ﯞﻩ ﻳﯚﻟﯩﻨﯩﺸﯩﻨﻰ ﺑﻪﻟﮕﯩﻠﻪﺵ ﺋﯩﻘﺘﯩﺪﺍﺭﯨﻐﺎ ﺋﯩﮕﻪ.
OrderByﺑﯩﻠﻪﻥ OrderByDescendingﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺋﻪﮔﻪﺭ Sqlﺋﺎﺭﻗﯩﻠﯩﻖ ﺳﺎﻧﺪﺍﻥ ﻣﻪﺷﻐﯘﻻﺗﻰ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﭗ ﺑﺎﻗﻘﺎ ﺑﻮﻟﺴﯩﯖﯩﺰ ﻧﻪﺗﯩﺠﯩﻠﻪﺭﻧﻰ ﻣﻪﻟﯘﻡ ﺷﻪﺭﺗﻜﻪ ﺋﺎﺳﺎﺳﻪﻥ ﺳﻮﺭﺗﻼﺵ)ﺗﯩﺰﯨﺶ( ﻧﯩﯔ ﻣﯘﮬﯩﻢ ﻧﯘﺧﺘﺎ ﺋﯩﻜﻪﻧﻠﯩﻜﯩﻨﻰ ﺋﻪﺳﻜﻪﺭﺗﯩﺸﯩﯖﯩﺰﻧﯩﯔ ﮬﺎﺟﯩﺘﻰ ﻳﻮﻕ. Linqﺑﻮﻟﺴﺎ orderingﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﻧﻪﺗﯩﺠﯩﺴﯩﮕﻪ ﺋﺎﺷﻤﺎ ﻳﺎﻛﻰ ﻛﯧﻤﻪﻳﺘﯩﻠﯩﻚ ﺳﻮﺭﺗﻼﺵ ﺋﯧﻠﯩﭗ ﺑﺎﺭﺍﻻﻳﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ :ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ Italyﺑﻮﻟﻐﺎﻥ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ﻧﺎﻣﻰ ﺑﯩﻠﻪﻥ ﺷﻪﮬﻪﺭ ﺧﺎﺳﻠﯩﻘﻠﯩﺮﯨﻐﺎ ﻧﺎﻣﯩﻨﯩﯔ ﺋﺎﻟﻔﺎﺑﯩﺖ ﺟﻪﺩﯞﯦﻠﯩﺪﯨﻜﻰ)ﺋﯧﻨﮕﯩﻠﯩﺰﻻﺭﻧﯩﯔ ﺋﯧﻠﯩﭙﺒﻪ ﺗﻪﺭﺗﯩﭙﻰ( ﻛﯧﻤﯩﻴﯩﭗ ﺑﯧﺮﯨﺶ ﺗﻪﺭﺗﯩﭙﻰ ﺑﻮﻳﯩﭽﻪ ﺗﯩﺰﯨﻠﻐﺎﻥ ﮬﺎﻟﯩﺘﯩﺪﻩ ﺋﯧﺮﯨﺸﯩﺶ ﺋﯜﭼﯜﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛﻮﺩ ﻳﯧﺰﯨﺶ ﻣﯘﻣﻜﯩﻦ: ﻛﻮﺩ 4.11
var expr = from c in customers where c.Country == Countries.Italy orderby c.Name descending select new { c.Name, c.City }; ﻳــﯘﻗﯩﺮﯨﻘﻰ ﺳﯜﺭﯛﺷ ـﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨــﺴﻰ ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﻣﯘﻧﺎﺳــﯩﯟﻩﺗﻠﯩﻚ ﺋﻪﻧــﺪﯨﺰﯨﻠﻪﺭﺩﯨﻜﻰ ﻣــﺎﺱ ﻛﯧﯖﻪﻳــﺘﻤﻪ ﻣﯧﺘﻮﺩﻻﺭ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻛﻮﺩ 15ﺩﯨﻜﻰ ﺟﯜﻣﻠﯩﻠﻪﺭﮔﻪ ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﯩﻨﯩﺪﯗ.
public static IOrderedSequence OrderBy( this IEnumerable source, Func keySelector); public static IOrderedSequence OrderBy( this IEnumerable source, Func keySelector, IComparer comparer); public static IOrderedSequence OrderByDescending( this IEnumerable source, Func keySelector); public static IOrderedSequence OrderByDescending( this IEnumerable source, Func keySelector, IComparer comparer);
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
15 ﻛﻮﺩ
var expr = customers .Where(c => c.Country == Countries.Italy) .OrderByDescending(c => c.Name) .Select(c => new { c.Name, c.City } );
ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰThenByDescending ﺑﯩﻠﻪﻥThenBy ﺋﻪﮔﻪﺭ ﻧﻪﺗﯩﺠﯩﻨﻰ ﺑﯩﺮﺩﯨﻦ ﺋـﺎﺭﺗﯘﻕ ﺷـﻪﺭﺕ ﺑﯩـﻠﻪﻥ ﺳـﻮﺭﺗﻠﯩﻤﺎﻗﭽﻰ ﺑﻮﻟـﺴﯩﯖﯩﺰ ﺑـﯘ ﺋﯩﻜﻜـﻰ ﻣﻪﺷـﻐﯘﻻﺗﭽﻰ : ﺗﯚﯞﻩﻧﺪﯨﻜﯩﻠﻪﺭ ﺋﯘﻻﺭﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ.ﮬﺎﺟﯩﺘﯩﯖﯩﺰﺩﯨﻦ ﭼﯩﻘﯩﺪﯗ
public static IOrderedSequence ThenBy( this IOrderedSequence source, Func keySelector); public static IOrderedSequence ThenBy( this IOrderedSequence source, Func keySelector, IComparer comparer); public static IOrderedSequence ThenByDescending( this IOrderedSequence source, Func keySelector); public static IOrderedSequence ThenByDescending( this IOrderedSequence source, Func keySelector, IComparer comparer); ﻣﻪﺷـــــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻧﯩﯖﻜﯩﮕﻪOrderByDescending ﺑﯩـــــﻠﻪﻥOrderBy ﺋﯘﻻﺭﻧﯩـــــﯔ ﺋﻪﻧـــــﺪﯨﺰﯨﻠﯩﺮﻯ ﻧـﻰ ﭘﻪﻗﻪﺕThenByDescending ﺑﯩـﻠﻪﻥThenBy ، ﭘﻪﺭﻗﻠﯩـﻖ ﻳﯧـﺮﻯ ﺷـﯘﻛﻰ.ﺋﻮﺧﺸﯩﺸﯩﭗ ﻛﯧﺘﯩـﺪﯗ ﺷـﯘﯕﺎ ﺑـﯘ.( ﻏـﺎ ﺑﻮﻟﻤﺎﻳـﺪﯗIEnumerable ) ﮔﯩﻼ ﻗﻮﻟﻠﯩﻨﯩﺸﻘﺎ ﺑﻮﻟﯩﺪﯗIOrderedSequence ﻧﯩــﯔ ﻛﻪﻳﻨــﻰ ﺋــﯘﻻﭘﻼ ﺋﯩــﺸﻠﻪﺗﻜﯩﻠﻰOrderByDescending ﺑﯩــﻠﻪﻥOrderBy ﺋﯩﻜﻜﯩــﺴﯩﻨﻰ ﭘﻪﻗﻪﺕ ﻻﺭﺩﯨـــﻦ ﻛﻪﻟـــﮕﻪﻥ ﻧﻪﺗﯩـــﺠﻪOrderBy ﭼـــﯜﻧﻜﻰ. ﻣﯘﺳـــﺘﻪﻗﯩﻞ ﺋﯩﺸﻠﯩﺸﺘـــﺸﻜﻪ ﺑﻮﻟﻤﺎﻳـــﺪﯗ،ﺑﻮﻟﯩـــﺪﯗ . ﻧﻰ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥIOrderedSequence :ﺗﯚﯞﻩﻧﺪﻩ ﺑﯘﻧﯩﯖﻐﺎ ﺑﯩﺮ ﻣﯩﺴﺎﻝ ﻛﻪﻟﺴﯘﻥ
46
47
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﻮﺩ 4.12
var expr = customers .Where(c => c.Country == Countries.Italy) .OrderByDescending(c => c.Name) .ThenBy(c => c.City) ;) .Select(c => new { c.Name, c.City } ﺋﺎﯞﯞﺍﻝ ﻧﺎﻣﯩﻨﯩـﯔ ﻛﯧﻤﻪﻳﻤﯩـﺴﻰ ﺑـﻮﻳﯩﭽﻪ ﺗﯩﺰﯨـﭗ ﺋﺎﻧـﺪﯨﻦ ﺋﺎﻟـﺪﯨﻨﻘﻰ ﺗﯩـﺰﯨﺶ ﻧﻪﺗﯩﺠﯩـﺴﯩﻨﻰ ﺷـﻪﮬﻪﺭﻧﯩﯔ ) (Cityﺋﺎﺷﻤﯩﺴﻰ ﺑﻮﻳﯩﭽﻪ ﺗﯩﺰﯨﺪﯗ. ﻳﯘﻗﯩﺮﯨﻘﻰ ﺟﯜﻣﻠﯩﻠﻪﺭﻧﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻣﯘﻧﺪﺍﻕ ﺋﯩﭙﺎﺩﯨﻠﻪﺵ ﻣﯘﻣﻜﯩﻦ: ﻛﻮﺩ 4.12
var expr = from c in customers where c.Country == Countries.Italy orderby c.Name descending, c.City select new { c.Name, c.City }; ﺋﻪﮔﻪﺭ ﺋـــﯚﺯﯨﯖﯩﺰ ﺳﯧﻠﯩـــﺸﺘﯘﺭﯗﻟﻤﺎﻗﭽﻰ ﺑﻮﻟﻐـــﺎﻥ ﺗﯩﭙﯩﯖﯩﺰﻏـــﺎ ﻧﯩـــﺴﺒﻪﺗﻪﻥ ﺳﯧﻠﯧـــﺸﺘﯘﺭﯗﺵ ﻗﺎﺋﯩﺪﯨـــﺴﯩﻨﻰ ﺑﯧﻜﯩﺘﻤﯩﮕﻪﻥ ﺑﻮﻟـﺴﯩﯖﯩﺰ Linq ،ﺳﯩـﺴﺘﯧﻤﯩﻨﯩﯔ ﻛﯚﯕﯜﻟـﺪﯨﻜﻰ ﻗﯩﻤـﻤﻪﺕ ﮬـﺎﻟﯩﺘﻰ ﺑـﻮﻳﯩﭽﻪ ﺳﯧﻠﯩـﺸﺘﯘﺭﯗﺵ ﺋﯧﻠﯩﭗ ﺑﺎﺭﯨﺪﯗ .ﺋﻪﮔﻪﺭ ﺋﺎﻻﮬﯩﺪﻩ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺵ ﺯﯙﺭﯨﻴﯩﺘﻰ ﺗﯘﻏﯘﻟﺴﺎ ،ﻣﻪﺳﯩﻠﻪﻥ ﺧﯧﺮﯨـﺪﺍﺭﻻﺭﻧﯩﯔ ﺋﯩـﺴﻤﻰ ﺋﯘﻳﻐﯘﺭﭼﻪ ﻳﯧﺰﯨﻠﻐﺎﻥ ﺑﻮﻟﺴﺎ ﺋﯘﻻﺭﻧﻰ ﺋﯘﻳﻐﯘﺭ ﺗﯩﻠﻰ ﺋﯧﻠﯩﭙﺒﻪ ﺗﻪﺭﺗﯩﭙﻰ ﺑـﻮﻳﯩﭽﻪ ﺗﯩـﺰﯨﺶ ﻛﯧـﺮﻩﻙ .ﺑﯘﻧـﺪﺍﻕ ﺋﻪﮬﯟﺍﻟﻼﺭﺩﺍ ﺋﻪﻣﻪﻟﯩﻲ ﺋﻪﮬﯟﺍﻟﻐﺎ ﺧﺎﺱ ﺑﻮﻟﻐـﺎﻥ ﺳﯧﺴﻠﯩـﺸﺘﯘﺭﻏﯘﭺ ﻳﺎﺳـﺎﭖ ،ﺳـﻮﺭﺗﻼﺵ ﻣﻪﺷـﻐﯘﻻﺗﭽﯩﻠﯩﺮﯨﻐﺎ ﭘﺎﺭﺍﻣﯧﺘﯩﺮ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻳـﻮﻟﻼﭖ ﺑﯧﺮﯨـﺸﯩﻤﯩﺰ ﻛﯧـﺮﻩﻙ .ﻣﻪﺳـﯩﻠﻪﻥ :ﺋـﺎﯞﯞﺍﻝ ﺋﯘﻳﻐـﯘﺭﭼﻪ ﺧﻪﺗﻨـﻰ ﺋـﯚﺯ ﺋﯩﭽﯩـﮕﻪ ﺋﺎﻟﻐﺎﻥ ﺋﯩﻜﻜﻰ ﺩﺍﻧﻪ stringﻧﻰ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺵ ﺗﯜﺭﯨﻨﻰ ﺗﻪﻣﯩﻨﻠﻪﭖ: ﻛﻮﺩ 16
using System.Globalization; private class UyghurComparer: IComparer<string> { public int Compare(string x, string y) { ]ﻗﺎﺋﯩﺪﯨﮕﻪ ﺋﺎﺳﺎﻥ ﺳﯧﻠﯩﺸﺘﯘﺭﻏﺎﻧﺪﯨﻜﻰ ﻧﻪﺗﯩﺠﻪ[ return } } ﺋﺎﻧﺪﯨﻦ ﺋﯘﻧﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺋﯘﺳﯘﻝ ﺑﻮﻳﯩﭽﻪ ﺋﯩﺸﻠﯩﺘﯩﻤﯩﺰ: ﻛﻮﺩ 17
IEnumerable orders = customers .SelectMany(c => c.Orders) .OrderBy(o => o.Month, new MonthComparer());
48
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
Reverceﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ )ﻛﯚﻣﺘﯜﺭﯛﺵ( ﺑﻪﺯﯨﺪﻩ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩﺴﯩﻨﯩﻨﯩﯔ ﺗﻪﺭﺗﯩﭙﯩﻨﻰ ﺋﻪﻛﺴﯩﮕﻪ ﺋﯚﺭﯛﺵ ﺋﯧﮫﺘﯩﻴـﺎﺟﻰ ﺗﯘﻏﯘﻟﯩـﺪﯗ Linq .ﺩﺍ ﺑﯘﻧـﺪﺍﻕ ﺋﻪﮬﯟﺍﻟﻐﺎ ﻧﯩﺴﺒﻪﺗﻪﻥ Reverceﻧﺎﻣﻠﯩﻖ ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ ﺗﻪﻣﯩﻨﻠﻪﻧﮕﻪﻥ .ﻳﻪﻧﻰ:
public static IEnumerable Reverse( this IEnumerable source); ﺗﯚﯞﻩﻧﺪﻩ Reverceﻧﻰ ﺋﯩﺸﻠﯩﺘﯩﺸﺘﯩﻦ ﺋﺎﺩﺩﻯ ﺑﯩﺮ ﻣﯩﺴﺎﻝ: ﻛﻮﺩ 4.14
var expr = customers .Where(c => c.Country == Countries.Italy) .OrderByDescending(c => c.Name) .ThenBy(c => c.City) .Select(c => new { c.Name, c.City } ) ;)( .Reverse ﺑﯩﺮﺍﻕ Linqﺩﺍ Reverceﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺋﯜﭼـﯜﻥ ﻣﻪﺧـﺴﯘﺱ ﺧـﺎﺱ ﻧـﺎﻡ ﺑﯧﻜﯩـﺘﯩﻠﻤﯩﮕﻪﻥ )ﻣﻪﺳـﯩﻠﻪﻥ Selectﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺋﯜﭼﯜﻥ selectﺧـﺎﺱ ﻧـﺎﻣﻰ ﺑﯧﻜﯩـﺘﯩﻠﮕﻪﻥ( ،ﺷـﯘﯕﺎ ﺳﯜﺭﯛﺷـﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨـﺴﻰ ﻣﻪﺯﻛﯘﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﺶ ﺋﯜﭼﯜﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻣﯩﺴﺎﻟﺪﺍ ﻛﯚﺭﺳـﯩﺘﯩﻠﮕﻪﻧﺪﻩﻙ ﺋﯘﺳـﯘﻝ ﻗـﻮﻟﻠﯩﻨﯩﺶ ﻛﯧﺮﻩﻙ: ﻛﻮﺩ 4.15
var expr = (from c in customers where c.Country == Countries.Italy orderby c.Name descending, c.City select new { c.Name, c.City } ;)( ).Reverse
Groupingﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﮔﯘﺭﭘﯩﻼﺵ( ﺳـــﺎﻥ -ﺳـــﯩﻔﯩﺮ ﺗﯩﺰﻣﯩﻠﯩﺮﯨﻨـــﻰ )ﺋﻪﺯﺍ ﺗﯩﺰﻣﯩﻠﯩـــﺮﻯ( ﻗﺎﻧـــﺪﺍﻕ ﺗـــﺎﻟﻼﺵ ،ﺳـــﯜﺯﯛﺵ ﯞﻩ ﺳـــﻮﺭﺗﻼﺵ ﻣﻪﺷــﻐﯘﻻﺗﻠﯩﺮﯨﻨﻰ ﻛــﯚﺭﯛﭖ ﺋﯚﺗﺘــﯘﻕ .ﺑﻪﺯﯨــﺪﻩ ﻳــﯘﻗﯩﺮﯨﻘﻰ ﻣﻪﺷــﻐﯘﻻﺗﻼﺭﺩﯨﻦ ﺋﯧﺮﯨــﺸﻜﻪﻥ ﺋﻪﺯﺍﻻﺭﻧــﻰ ﺑﯩــﺮﻻ ﺗﻮﭘﻼﻣﻐﺎ ﺋﻮﺭﯗﻧﻼﺷﺘﯘﺭﻣﺎﻱ ،ﻣﻪﻟـﯘﻡ ﺷـﻪﺭﺗﻜﻪ ﺋﺎﺳﺎﺳـﻪﻥ ﺋﻮﺧـﺸﯩﻤﯩﻐﺎﻥ ﮔﯘﺭﭘﯩﻼﺭﻏـﺎ ﺑﯚﻟـﯜﺵ ﺯﻭﺭﯛﺭﯨﻴﯩﺘـﻰ ﺗﯘﻏﯘﻟﯩـــﺪﯗ Linq .ﺑﯘﻧـــﺪﺍﻕ ﺋﻪﮬﯟﺍﻟﻼﻧﯩﻤـــﯘ ﺋﻮﻳﻼﺷـــﻘﺎﻥ ﯞﻩ ﻣﯘﻧﺎﺳـــﯩﭗ ﻣﻪﺷـــﻐﯘﻻﺗﭽﻰ GroupByﻧـــﻰ ﺗﻪﻣﯩﻨﻠﯩﮕﻪﻥ .ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ:
49
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
public static IEnumerable> GroupBy( this IEnumerable source, Func keySelector); public static IEnumerable> GroupBy( this IEnumerable source, Func keySelector, IEqualityComparer comparer); public static IEnumerable> GroupBy( this IEnumerable source, Func keySelector, Func elementSelector); public static IEnumerable> GroupBy( this IEnumerable source, Func keySelector, Func elementSelector, IEqualityComparer comparer); ﺑـﺎﺭﻟﯩﻖ ﺋﻪﻧـﺪﯨﺰﯨﻠﯩﺮﻯ >> IEnumerable IGrouping Enumerable
var expr = customers.GroupBy(c => c.Country); foreach(IGrouping customerGroup in expr) { Console.WriteLine("Country: {0}", customerGroup.Key); foreach(var item in customerGroup) { Console.WriteLine(item); } } ﻛﻮﺩ 4.16ﺩﻩ ﻛﯚﺭﺳﯩﺘﯩﻠﮕﻪﻧﺪﻩﻙ ﮬﻪﺭﺑﯩﺮ ﮔﯘﺭﭘﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﻰ)ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ ﺋﻮﺧﺸﺎﺵ ﺑﻮﻟﻐـﺎﻥ ﺧﯧﺮﯨﺪﺍﺭﻻﺭ( ﭼﺎﺭﻻﺷﺘﯩﻦ ﺋـﺎﯞﺍﻝ ﭼﻮﻗـﯘﻡ ﮔﻮﺭﯗﭘﯩﻼﺭﻧﯩـﯔ ﺋـﺎﭼﻘﯘﭺ ﺳـﯚﺯﯨﻨﻰ ﭼـﺎﺭﻻﺵ ﻛﯧـﺮﻩﻙ .ﮬﻪﺭ ﺑﯩـﺮ ﮔﯘﺭﭘــﺎ > IGrouping
www.udmish.cn
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
4.17 ﻛﻮﺩ
var expr = from c in customers group c by c.Country; foreach(IGrouping customerGroup in expr) { Console.WriteLine("Country: {0}", customerGroup.Key); foreach(var item in customerGroup) { Console.WriteLine(item); } } ﻧﯩﯔ ﺋﻪﯓGroupBy ﺑﯘ ﻗﯧﺘﯩﻢ. ﺩﺍ ﮔﯘﺭﭘﯩﻼﺷﻘﺎ ﺋﺎﻻﻗﯩﺪﺍﺭ ﻳﻪﻧﻪ ﺑﯩﺮ ﺧﯩﻞ ﻣﯩﺴﺎﻝ ﺑﯧﺮﯨﻠﺪﻯ4.18 ﻛﻮﺩ .ﺋﺎﺧﯩﺮﯨﻘﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﻰ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ 4.18 ﻛﻮﺩ
var expr = customers .GroupBy(c => c.Country, c => c.Name); foreach(IGrouping customerGroup in expr) { Console.WriteLine("Country: {0}", customerGroup.Key); foreach(var item in customerGroup) { Console.WriteLine(" {0}", item); } } :ﻳﯘﻗﯩﺮﯨﻘﻰ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﻨﯩﯔ ﺋﯩﺠﺮﺍ ﻧﻪﺗﯩﺠﯩﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ
Country: Italy Paolo Marco Country: USA James Frank
50
51
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
Joinﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﮬﻪﻣﺪﻩﻡ( Joinﻣﻪﺷـــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ Linqﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﺋﯩﭽﯩـــﺪﯨﻜﻰ ﺗﯩﺰﻣﯩﻠﯩـــﺮﻯ ﺋﺎﺭﯨـــﺴﯩﺪﯨﻜﻰ ﻣﯘﻧﺎﺳـــﯩﯟﻩﺗﻨﻰ ﺑﻪﻟﮕﯩﻠﻪﺷــﻜﻪ ﺋﯩــﺸﻠﯩﺘﯩﻠﯩﺪﯗ SQL .ﺳــﺎﻧﺪﺍﻥ ﻣﻪﺷــﻐﯘﻻﺗﯩﻨﻰ ﺋﯧﻠﯩــﭗ ﺋﯧﻴﺘــﺴﺎﻕ ﺋﺎﺳﺎﺳــﻪﻥ ﮬﻪﺭﻗﺎﻧــﺪﺍﻕ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺑﯩـﺮ ﻳـﺎﻛﻰ ﺑﯩﺮﻗـﺎﻧﭽﻪ ﺟﻪﺩﯞﻩﻟﻨـﻰ ﮬﻪﻣﺪﻩﻣﻠﻪﺷـﺘﯜﺭﯨﺪﯗ Linq .ﺩﺍ ،ﺑﯩـﺮ ﻗﯩـﺴﯩﻢ ﮬﻪﻣـﺪﻩﻡ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﻳﯘﻗﯩﺮﯨﻘﯩﺪﻩﻙ ﺧﯘﻟﻘﻨﻰ ﺋﯚﺯﯨﮕﻪ ﻣﯘﺟﻪﺳﺴﻪﻣﻠﻪﺷﺘﯜﺭﮔﻪﻥ.
) Joinﮬﻪﻣﺪﻩﻡ ( ﺷﻪﻙ-ﺷﯚﺑﯩﺴﯩﺰﻛﻰ Joinﺑﻮﻟﺴﺎ ﮬﻪﻣﺪﻩﻡ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﯩﭽﯩـﺪﯨﻜﻰ ﺗـﯘﻧﺠﻰ ﻣﻪﺷـﻐﯘﻻﺗﭽﻰ .ﺋﯘﻧﯩـﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ:
public static IEnumerable Join( this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector); public static IEnumerable Join( this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector, IEqualityComparer comparer); Joinﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﺩﺍ ﺗﯚﺕ ﺩﺍﻧﻪ ﻛﯚﭘﻤﺎﺱ ﺗﯩﭙﻨﯩﯔ ﻳﻮﻟﻠﯩﻨﯩﺸﯩﻨﻰ ﺗﻪﻟﻪﭖ ﻗﯩﻠﯩﺪﯗ T .ﺑﻮﻟـﺴﺎ ﺳﯩﺮﺗﻘﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﺎ ﺗﯩﭙﯩﻐﺎ ﯞﻩﻛﯩﻠﻠﯩﻚ ﻗﯩﻠﯩﺪﯗ U ،ﺑﻮﻟﺴﺎ ﺋﯩﭽﻜﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣـﺎ ﺗﯩﭙﯩﻨـﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﻳـﺪﯗ. ﻛﯚﺭﺳـﻪﺗﻤﻪ
outerKeySelectorﺑﯩـﻠﻪﻥ innerKeySelectorﻻﺭ ﺑﻮﻟـﺴﺎ ﺳـﯩﺮﺗﻘﻰ ﯞﻩ ﺋﯩﭽﻜـﻰ ﻣﻪﻧـﺒﻪ
ﺗﯩﺰﻣﯩﻠﯩﺮﯨــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﯩــﯔ ﺋــﺎﭼﻘﯘﭼﻠﯘﻕ ﺳــﯚﺯﻟﯩﺮﯨﻨﻰ ﻗﺎﻧــﺪﺍﻕ ﭘﻪﺭﻕ ﺋﯧﺘﯩــﺸﻨﻰ ﺋﯧﻴﺘﯩــﭗ ﺑﯧﺮﯨــﺪﯗ .ﺑــﯘ ﺋﺎﭼﻘﯘﭼﻠﯘﻕ ﺳﯚﺯﻟﻪﺭﻧﻰ ﮬﻪﺭ ﺋﯩﻜﻜﯩﻠﯩﺴﻰ Kﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﯘﭖ Join ،ﺋﯘﻻﺭﻧﯩﯔ ﺗﻪﯕﻠﯧﻜﯩﻨﻰ ﺋﯚﺯﯨﮕﻪ ﺷﻪﺭﺕ ﻗﯩﻠﯩﺪﯗ V .ﺑﻮﻟﺴﺎ ﺋﺎﯓ ﺋﺎﺧﯩﺮﯨﻘﻰ ﻛﯚﭘﻤﺎﺱ ﺗﯩﭗ ﺑﻮﻟﯘﭖ ﺋﯘ Joinﻧﯩﯔ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩـﺴﯩﺪﯨﻜﻰ ﮬﻪﺭﺑﯩـﺮ ﺋﻪﺯﺍﻧﯩﯔ ﺗﯩﭙﯩﻨﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﻳﺪﯗ. Joinﻧﯩﯔ ﺋﯩﻜﻜﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﺳﯧﻠﯩﺸﺘﯘﺭﻏﯘﭼﻘﺎ ﺋﻮﺭﯗﻥ ﺑﯧﺮﯨﻠﮕﻪﻥ ﺑﻮﻟﯘﭖ ،ﮬﻪﻣﺪﻩﻣﻠﻪﺷـﻤﻪﻛﭽﻰ ﺑﻮﻟﻐــﺎﻥ ﺋﯩﻜﻜــﻰ ﺗﯩﺰﻣﯩﻨﯩــﯔ ﺋــﺎﭼﻘﯘﭼﻠﯘﻕ ﺳــﯚﺯﻟﯩﺮﯨﻨﻰ ﺳﯧﻠﯩــﺸﺘﯘﺭﺷﻘﺎ ﺋﯩــﺸﻠﯩﺘﯩﻠﯩﺪﯗ .ﺑﯘﻧﯩــﯔ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﻕ ﻗﺎﺋﯩﺪﯨــﺴﯩﻨﻰ ﺧﺎﺳﻼﺷﺘﯘﺭﺍﻻﻳــﺴﯩﺰ .ﺋﻪﮔﻪﺭ ﻣﻪﺯﻛــﯘﺭ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻏــﺎ Nullﺑﯧﺮﯨﻠــﺴﻪ ﻳــﺎﻛﻰ ﺑﯩﺮﻧﭽــﻰ ﺧﯩــﻞ ﺋﻪﻧﺪﯨﺰﯨــﺴﻰ ﺋﯩﺸﻠﯩﺘﯩﻠــﺴﻪ ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﺵ ﺋﯜﭼــﯜﻥ ﻛﯚﯕﯜﻟــﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗــﻜﻪ ﺑﻪﻟﮕﯩــﻠﻪﭖ ﻗﻮﻳﯘﻟﻐﺎﻥ ﺳﯧﻠﺸﺘﯘﺭﻏﯘﭼﻰ EqualityComparer.Defaultﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ.
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
ﺧﯧﺮﯨــﺪﺍﺭﻻﺭﻧﻰ ﺋﯘﻻﺭﻧﯩــﯔ ﺯﺍﻛــﺎﺯﻟﯩﺮﻯ ﯞﻩ. ﻧــﻰ ﻣﯩــﺴﺎﻝ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﭼﯜﺷــﯜﻧﯜﭖ ﺑﺎﻗــﺎﻳﻠﻰJoin ﺋﻪﻣــﺪﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺯﺍﻛﺎﺯﻻﺭﻏﺎ ﻣﺎﺱ ﻣﻪﮬﺴﯘﻻﺗﻼﺭﻧﻰ.ﻣﻪﮬﺴﯘﻻﺗﻼﺭ ﺑﯩﻠﻪﻥ ﺑﺎﻏﻼﭖ ﺋﻮﻳﻼﭖ ﻛﯚﺭﯛﯓ :ﮬﻪﻣﺪﻩﻣﻠﻪﺷﺘﯜﺭﯨﺪﯗ 4.19 ﻛﻮﺩ
var expr = customers .SelectMany(c => c.Orders) .Join( products, o => o.IdProduct, p => p.IdProduct, (o, p) => new {o.Month, o.Shipped, p.IdProduct, p.Price }); :ﻳﯘﻗﯩﺮﯨﻘﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻧﻪﺗﯩﺠﻪ ﭼﯩﻘﯩﺮﯨﺪﯗ
{Month=January, Shipped=False, IdProduct=1, Price=10} {Month=May, Shipped=True, IdProduct=2, Price=20} {Month=July, Shipped=False, IdProduct=1, Price=10} {Month=December, Shipped=True, IdProduct=3, Price=30} {Month=January, Shipped=True, IdProduct=3, Price=30} {Month=July, Shipped=False, IdProduct=4, Price=40} lambda. ﺑﻮﻟﺴﺎ ﺋﯩﭽﻜـﻰ ﺗﯩﺰﻣﯩﻐـﺎ ﯞﻩﻛﯩﻠﻠﯩـﻚ ﻗﯩﻠﯩـﺪﯗproducts ، ﺳﯩﺮﺗﻘﻰ ﺗﯩﺰﻣﯩﻐﺎorders ﺑﯘ ﻣﯩﺴﺎﻟﺪﺍ . ﺗﯩﭙﻠﯩﻖProduct ﯞﻩOrder ﺋﺎﻳﺮﯨﻢ ﮬﺎﻟﺪﺍ- ﻻﺭ ﺋﺎﻳﺮﯨﻢp ﺑﯩﻠﻪﻥo ﺋﯩﭙﺎﺩﯨﺴﯩﺪﯨﻜﻰ : ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻳﯧﺰﯨﺶ ﻣﯘﻣﻜﯩﻦ، ﺟﯜﻣﻠﯩﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﯩﭙﺎﺩﯨﻠﯩﺴﻪﻙSql ﺋﻪﮔﻪﺭ ﻳﯘﻗﯩﺮﯨﻘﻰ ﺋﯩﭙﺎﺩﯨﻨﻰ
SELECT o.Month, o.Shipped, p.IdProduct, p.Price FROM Orders AS o INNER JOIN Products AS p ON o.IdProduct = p.IdProduct :ﺋﻪﮔﻪﺭ ﺋﯩﭙﺎﺩﯨﻨﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻳﺎﺯﺳﺎﻕ ﺗﯚﯞﻩﻧﺪﯨﻜﺪﻩﻙ ﺑﻮﻟﯩﺪﯗ 4.20 ﻛﻮﺩ
var expr = from c in customers from o in c.Orders join p in products on o.IdProduct equals p.IdProduct select new {o.Month, o.Shipped, p.IdProduct, p.Price };
52
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
ﻳﯘﻗﯩﺮﯨﻘﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﺪﻩ ﺩﯨﻘﻘﻪﺕ ﻗﯩﻠﯩﺸﻘﺎ ﺗﯩﮕﯩﺸﻠﯩﻚ ﻳﯧﺮﻯ ﺷﯘﻛﻰ
(o.IdProduct equals p.IdProduct) ﺳــﯩﺮﺗﻘﻰ ﺗﯩﺰﻣــﺎ ﺑﺎﺷــﺘﺎ ﺋﯩﭽﻜــﻰ ﺗﯩﺰﻣــﺎ: ﻳﻪﻧــﻰ.ﺑــﯘ ﺋﯩﻜﻜﯩــﺴﯩﻨﯩﯔ ﺗﻪﺭﺗﯩﭙﻨــﻰ ﺋﯚﺯﮔﻪﺭﺗﯩــﺸﻜﻪ ﺑﻮﻟﻤﺎﻳــﺪﯗ .ﺋﺎﺧﯩﺮﯨﺪﺍ ﻛﯧﻠﯩﺸﻰ ﻛﯧﺮﻩﻙ
ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰGroupJoin ﻏـﺎ ﺋﻮﺧﺸﯩـﺸﯩﭗ ﻛﯧﺘﯩـﺪﯨﻐﺎﻥRIGHT OUTER JOIN ﻳـﺎﻛﻰLEFT OUTER JOIN ﺩﯨﻜـﻰSql . ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﻳﺎﺧــﺸﻰ ﺗــﺎﻟﻼﺵGroupJoin .ﺋﯩﻘﺘﯩــﺪﺍﺭﻧﻰ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﯗﺵ ﺋﯜﭼــﯜﻥ : ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯖﻜﯩﮕﻪ ﺋﯩﺘﺎﻳﯩﻦ ﺋﻮﺧﺸﯩﺸﯩﭗ ﻛﯧﺘﯩﺪﯗJoin ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ
public static IEnumerable GroupJoin( this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func, V> resultSelector); public static IEnumerable GroupJoin( this IEnumerable outer, IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func, V> resultSelector, IEqualityComparer comparer); ﮬـــﺎﺯﯨﺮﭼﻪ ﻛـــﯚﭖ،ﺋﻪﻣﻪﻟﯩـــﻲ ﺋﯩﺸﻠﯩﺘﯩﻠﯩـــﺸﯩﻨﻰ ﺗﯚﯞﻩﻧـــﺪﯨﻜﻰ ﻣﯩـــﺴﺎﻝ ﺋـــﺎﺭﻗﯩﻠﯩﻖ ﮬـــﯧﺲ ﻗﯩﻠﯩﯟﯦﻠﯩـــﯔ .ﺗﻮﺧﺘﺎﻟﻤﺎﻳﻤﻪﻥ 4.21 ﻛﻮﺩ
var expr = products .GroupJoin( customers.SelectMany(c => c.Orders), p => p.IdProduct, o => o.IdProduct, (p, orders) => new { p.IdProduct, Orders = orders }); foreach(var item in expr) { Console.WriteLine("Product: {0}", item.IdProduct); foreach (var order in item.Orders) { Console.WriteLine(" {0}", order); }}
53
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
:ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ ﻳﯘﻗﯩﺮﯨﻘﻰ ﺟﯜﻣﻠﯩﻠﻪﺭﻧﯩﯔ ﺋﯩﺠﺮﺍ ﻧﻪﺗﯩﺠﯩﺴﻰ
Product: 1 3 - False - January – 1 10 - False - July – 1 Product: 2 5 - True - May – 2 Product: 3 20 - True - December – 3 10 - True - January – 3 Product: 4 Product: 5 20 - False - July – 5 Product: 6 ﺧـــﺎﺱ ﺳـــﯚﺯﻟﯩﺮﻯ ﺋـــﺎﺭﻗﯩﻠﯩﻖjoint…into… ﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﻰJoin ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨـــﺴﯩﺪﻩ : ﺑﯩﻠﻪﻥ ﺑﺎﺭﻩﯞﻩﺭ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ4.21 ﻛﻮﺩ.ﺋﯩﭙﺎﺩﯨﻠﯩﻨﯩﺪﯗ 4.23 ﻛﻮﺩ
var expr = from p in products join o in ( from c in customers from o in c.Orders select o ) on p.IdProduct equals o.IdProduct into orders select new { p.IdProduct, Orders = orders };
54
55
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
Setﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﺗﻮﭘﻼﻡ( Linqﺳﻪﭘﯩﺮﯨﻤﯩﺰ ﺋﯘﭼﯘﺭ ﺗﯩﺰﻣﯩﻠﯩﺮﯨﻐﺎ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﯩﺪﯨﻐﺎﻥ »ﺑﯩﺮﯨﻜﻤﯩﺴﻰ«» ،ﻛﻪﺳﻤﯩﺴﻰ« ﯞﻩ »ﺩﯨـﻦ ﺑﺎﺷﻘﺎ« ﻻﺭﺩﻩﻙ ﺋﻪﯓ ﺋﺎﺳﺎﺳﻰ ﻣﻪﺷﻐﯘﻻﺗﻼﺭﻏﺎ ﻛﯧﻠﯩﭗ ﻗﺎﻟﺪﻯ.
Distinctﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ )ﺗﻪﻛﺮﺍﺭﻧﻰ ﺗﺎﺯﯨﻼﺵ( ﺑﯩﺮﻗــﺎﻧﭽﻪ ﺧﯧﺮﯨــﺪﺍﺭ ﺋﻮﺧــﺸﺎﺵ ﺑﯩــﺮ ﻣﻪﮬــﺴﯘﻻﺗﻨﻰ ﺯﺍﻛــﺎﺯ ﻗﯩﻠﯩـﺸﻰ ﻣــﯘﻣﻜﯩﻦ .ﺩﯦــﻤﻪﻙ ﺳــﯩﺰ ﺧﯧﺮﯨــﺪﺍﺭﻻﺭ ﺯﺍﻛﺎﺯﻟﯩﺮﯨﺪﯨﻜﻰ ﻣﻪﮬﺴﯘﻻﺗﻼﺭﻧﻰ ﺋﻮﻗﯘﭖ ﭼﯩﻘﺴﯩﯖﯩﺰ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩﺴﯩﺪﺍ ﺗﻪﻛﺮﺍﺭ ﺋﻪﺯﺍ ﻛﯚﺭﯛﻟﯩـﺸﻰ ﻣـﯘﻣﻜﯩﻦ. ﻣﯘﺷﯘ ﺧﯩﻞ ﺗﻪﻛﺮﺍﺭﻟﯩﻘﻨﯩﯔ ﺋﺎﻟﺪﯨﻨﻰ ﺋﯧﻠﯩﺶ ﺋﯜﭼﯜﻥ ﻗﺎﻧﺪﺍﻕ ﻗﯩﻠﯩﺶ ﻛﯧﺮﻩﻙ؟ ﻣﯘﺷـﯘ ﺧﯩـﻞ ﻣﻪﺳـﯩﻠﻪ Sql ﺟﯜﻣﻠﯩﺴﯩﺪﻩ ﺋﺎﺩﻩﺗﺘﻪ Joinﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻰ ﺋﯩﭽﯩﺪﻩ DISTINCTﺧﺎﺱ ﺳـﯚﺯﯨﻨﻰ ﺋﯩـﺸﻠﯩﺘﯩﺶ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﮬﻪﻝ ﻗﯩﻠﯩﻨﺎﺗﺘﻰ Linq .ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻠﯩﺮﯨﺪﻩ ﺑﻮﻟﺴﺎ ﺑﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ ﺗﻮﭘﻼﻡ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻧﯩﯔ ﺋﻪﺯﺍﺳـﻰ ﺑﻮﻟﻐــﺎﻥ Distinct
ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﯩﻨﻰ ﺗﻪﻣﯩــﻨﻠﯩﮕﻪﻥ .ﺋﯘﻧﯩــﯔ ﺋﻪﻧﺪﯨﺰﯨــﺴﻰ ﺋﯩﻨﺘــﺎﻳﯩﻦ ﺋــﺎﺩﺩﻯ ﺑﻮﻟــﯘﭖ
ﭘﻪﻗﻪﺕ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﻨﯩﻼ ﻗﻮﺑﯘﻝ ﻗﯩﻠﯩﭗ ﺋﯘﻧﯩـﯔ ﺋﻪﺯﺍﻟﯧـﺮﻯ ﺋﺎﺭﯨـﺴﯩﺪﯨﻜﻰ ﺋـﯚﺯﮔﯩﭽﻪ ﺋﻪﺯﺍﻻﺭﻧـﻰ ﻗـﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﯨﺪﯗ. Distinctﺋﯜﭼﯜﻥ ﺑﯩﺮ ﻣﯩﺴﺎﻝ ﻛﻮﺩ 4.24ﺩﻩ ﺑﯧﺮﯨﻠﺪﻯ.
public static IEnumerable Distinct( this IEnumerable source);
ﻛﻮﺩ 4.24
var expr = customers .SelectMany(c => c.Orders) .Join(products, o => o.IdProduct, p => p.IdProduct, (o, p) => p) .Distinct(); ﮔﻪﺭﭼﻪ Distinctﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻐﺎ ﻣﺎﺱ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺧﺎﺱ ﺳﯚﺯﻯ ﺗﻪﻣﯩﻨﻠﻪﻧﻤﯩﮕﻪﻥ ﺑﻮﻟـﺴﯩﻤﯘ ،ﺋـﯘﻧﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﻧﻪﺗﯩﺠﯩﺴﻰ ﺋﯜﺳﺘﯩﮕﻪ ﻗﻮﻟﻠﯩﻨﺎﻻﻳﻤﯩﺰ .ﻣﻪﺳﯩﻠﻪﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ: ﻛﻮﺩ 4.25
var expr = (from c in customers from o in c.Orders join p in products
56
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
on o.IdProduct equals p.IdProduct select p ).Distinct(); ﻧﻮﺭﻣﺎﻝ ﮬﺎﻟﻪﺗﺘﻪ Distinctﺋﯧﻠﻤﯩﺘﻼﺭﻧـﻰ ﺋﯘﻻﺭﻧﯩـﯔ GetHashCodeﯞﻩ Equalsﻣﯧﺘـﻮﺩﻟﯩﺮﻯ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﺑﯩﺮ-ﺑﯩﺮﻯ ﺑﯩـﻠﻪﻥ ﺳﯧﻠﯩـﺸﺘﯘﺭﯨﺪﯗ ﯞﻩ ﺋﯚﺯﺋـﺎﺭﺍ ﭘﻪﺭﻗﻠﻪﻧﺪﯛﺭﯨـﺪﯗ .ﺋﻪﮔﻪﺭ ﺯﻭﺭﯛﺭ ﺗﯧﭙﯩﻠـﺴﺎ Distinctﻧﯩـﯔ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﻰ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﺋﯘﻧﯩﯖﻐـﺎ ﺋﯚﺯﯨﻤﯩﺰﻧﯩـﯔ ﺳﯧﻠﺸﺘﯘﺭﻏﯘﭼﯩـﺴﯩﻨﻰ ﻳـﻮﻟﻼﭖ ﺳﯧﻠﯩـﺸﺘﯘﺭﯗﺵ ﺧﯘﻟﻘﯩﻨﻰ ﻛﻮﻧﺘﺮﻭﻝ ﻗﯩﻼﻻﻳﻤﯩﺰ.
Union, Intersect, and Except Unionﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺋﯩﻜﻜﻰ ﺗﯩﺰﻣﺎ ﺋﯧﻠﯧﻤﯧﻨﺘﻠﯩﺮﯨﻨﻰ ﺗﻪﻛﺮﺍﺭﻟﯩﻘﻨـﻰ ﻳﻮﻗﺎﺗﻘـﺎﻥ ﺋﺎﺳﺎﺳـﺘﺎ ﺑﯩﺮﻟﻪﺷـﺘﯜﺭﯛﭖ ﭼﯩﻘﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 4.26
var expr = customers[1].Orders.Union(customers[2].Orders); ﺧﯘﺩﺩﻯ Distinctﻗـﺎ ﺋﻮﺧـﺸﺎﺵ ﺑﯘﻻﺭﻣـﯘ ﺋﯧﻠﻤﯧﻨﯩﺘﻠﯩﺮﻧـﻰ ﺳﯧﻠﯩـﺸﺘﯘﺭﯗﺵ ﺋﯜﭼـﯜﻥ GetHashCodeﯞﻩ Equalsﻣﯧﺰﻭﺩﻻﺭﻧــــﻰ ﺋﯩــــﺸﻠﺘﯩﺪﯗ)ﺑﯩﺮﯨﻨﭽــــﻰ ﺋﻪﻧﺪﯨﺰﯨــــﺴﯩﺪﻩ( .ﺋﻪﻟــــﯟﻩﺗﺘﻪ ،ﺧﺎﺳﻼﺷــــﺘﯘﺭﯗﻟﻐﺎﻥ ﺳﯧﻠﯩﺸﺘﯘﺭﻏﯘﭼﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﺸﻜﻪ ﻳﻮﻝ ﻗﻮﻳﻐﺎﻥ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﻤﯘ ﺑﺎﺭ .ﻣﯩﺴﺎﻟﻪﻥ ،ﻛﻮﺩ 4.26ﻧﯩﯔ ﻧﻪﺗﯩﺠﯩـﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺑﻮﻟﯩﺪﯗ.
10 ‐ False ‐ July – 1 20 ‐ True ‐ December – 3 20 ‐ True ‐ December ‐ 3 ﻧﻪﺗﯩﺠﻪ ﺋﻮﻳﻠﯩﻐﺎﻥ ﻳﯧﺮﯨﯖﯩﺰﺩﯨﻦ ﭼﯩﻘﻤﯩﻐﺎﻧﺪﻩﻛﻤﯘ؟ ﺋﺎﺧﯩﺮﯨﻘﻰ ﺋﯩﻜﻜﻰ ﻗـﯘﺭ ﺋﻮﭘﻤـﯘ ﺋﻮﺧـﺸﺎﺵ ﺗﯘﺭﯨـﺪﯨﻐﯘ، ﺋﻪﺟﯩﺒﺎ Distinctﻧﯩﯔ ﺭﻭﻟﻰ ﺑﻮﻟﻤﯩﻐﺎﻧﺪﯨﻤﯘ؟ »ﻣﯩـــﺴﺎﻟﻼﺭ ﺋﯜﭼـــﯜﻥ ﺗـــﯜﺭ ﻗﯘﺭﯗﻟﻤﯩـــﺴﻰ« ﺩﯨﻜـــﻰ ﺧﯧﺮﯨـــﺪﺍﺭ ﺋـــﻮﺑﻴﯧﻜﯩﺘﻠﯩﺮﯨﻨﻰ ﺩﻩﺳﻠﻪﭘﻠﻪﺷـــﺘﯜﺭﯛﺵ ﻛﻮﺩﯨﻐــﺎ)ﻣﻪﺯﻛــﯘﺭ ﻣﺎﻗﺎﻟﯩــﺪﯨﻜﻰ ﺑــﺎﺭﻟﯩﻖ ﻛــﻮﺩﻻﺭ ﻧﯩــﯔ ﻣﯩــﺴﺎﻝ ﻣﻪﺷــﻐﯘﻻﺕ ﺋــﻮﺑﯩﻜﺘﻰ( ﻧﻪﺯﻩﺭ ﺳــﺎﻟﯩﺪﯨﻐﺎﻥ ﺑﻮﻟﺴﺎﻕ ،ﺩﻩﺳﻠﻪﭘﻠﻪﺷﺘﯜﺭﯛﻟﮕﻪﻥ ﮬﻪﺭ ﺑﯩﺮ ﺯﺍﻛﺎﺯ ﺋﻪﺯﺍﺳﻰ) (orderﺑﻮﻟﺴﺎ Orderﻧﺎﻣﻠﯩﻖ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ)(引用 ﺗﯩﭙﻨﯩــﯔ ﺋﻮﺧــﺸﯩﻤﯩﻐﺎﻥ ﺋــﻮﺑﻴﯧﻜﯩﺘﻠﯩﺮﻯ .ﮔﻪﺭﭼﻪ ﺋﯩﻜﻜﯩﭽــﻰ ﺧﯧﺮﯨــﺪﺍﺭﻧﯩﯔ ﺋﯩﻜﻜﯩﻨﭽــﻰ ﺯﺍﻛــﺎﺯﻯ ﺑﯩــﻠﻪﻥ ﺋــﯜﭼﯩﻨﭽﻰ ﺧﯧﺮﯨــﺪﺍﺭﻧﯩﯔ ﺑﯩﺮﯨﻨﭽــﻰ ﺯﺍﻛــﺎﺯﻯ ﺳــﺎﻥ -ﺳــﯩﻔﯩﺮ ﺟﻪﮬﻪﺗــﺘﯩﻦ ﺋﻮﺧــﺸﺎﺵ ﺑــﻮﻟﻐﯩﻨﻰ ﺑﯩــﻠﻪﻥ ﺋﯘﻻﺭﻧﯩﯔ Hashﻛﻮﺩﻯ ﺋﻮﺧﺸﯩﻤﺎﻳﺪﯗ. ﻧﻪﺗﯩﺠﯩﺪﻩ ﺋﯘﻻﺭﻧﻰ ﺳﯧﻠﯩـﺸﺘﯘﺭﻏﺎﻧﺪﺍ ﻳﻪﻧﯩـﻼ ﺋﻮﺧـﺸﯩﻤﯩﻐﺎﻥ ﺋﻮﺑﻴﯧﻜﯩـﺖ ﺑﻮﻟـﯘﭖ ﭼﯩﻘﯩـﭗ Distinctﻧﯩـﯔ ﺗﻪﻛﺮﺍﺭﻻﺭﻧﻰ ﺳﯜﺯﯛﺵ ﺋﻪﮔﻠﯩﻜﯩﺪﯨﻦ)ﺋﻪﮔﻠﻪﻙ :ﺋﺎﺋﯩﻠﯩﻠﻪﺭﺩﻩ ﺋـﯘﻥ ﺗﺎﺳﻘﺎﺷـﻘﺎ ﺋﯩـﺸﻠﯩﺘﯩﻠﯩﺪﯨﻐﺎﻥ ﺳـﯜﺯﮔﯜﭺ( ﺋﯚﺗﯜﭖ ﻛﯧﺘﯩﺪﯗ.
57
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻗﻮﺷﯘﻣﭽﻪ ﺳﺎﯞﺍﺕ 1
ﻣﻪﻟﯘﻡ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭙﻨﯩﯔ ﺋﯩﻜﻜﻰ ﺋﻮﺑﻴﯧﻜﯩﺘﯩﻨﻰ )ﻣﻪﺳﯩﻠﻪﻥ ﺑﯩﺰﻧﯩﯔ ﻣﯩﺴﺎﻟﯩﻤﯩﺰﺩﯨﻜﻰ (Customerﺳﯩﺴﺘﯧﻤﺎ ﻛﯚﯕﯜﻟﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺕ ﮬﺎﻟﻪﺗﺘﻪ ﺳﯧﻠﯩﺸﺘﯘﺭﻏﺎﻧﺪﺍ ﮬﻪﺭﺑﯩﺮﯨﻨﯩﯔ Hash ﻛﻮﺩﯨﻨﻰ ﺳﯧﻠﯩﺸﺘﯘﺭﯨﺪﯗ .ﮔﻪﺭﭼﻪ ﺋﯘ ﺋﯩﻜﻜﯩﺴﯩﻨﯩﯔ ﺧﺎﺳﻠﯩﻘﻠﯩﺮﯨﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻯ ﺋﻮﺧﺸﺎﺵ ﺑﻮﻟﯩﺴﯩﻤﯘ ﻟﯧﻜﯩﻦ Hashﻛﻮﺩﻯ ﺋﻮﺧﺸﺎﺵ ﭼﯩﻘﻤﺎﻳﺪﯗ .ﭼﯜﻧﻜﻰ ﺋﯘﻻﺭ ﺑﻪﺭﯨﺒﯩﺮ ﺋﯩﻜﻜﻰ ﺋﻮﺑﻴﯧﻜﯩﺖ .ﮬﻪﺭﻗﺎﻧﺪﺍﻕ ﺗﯩﭙﻠﯩﻖ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩﯔ Hashﻛﻮﺩﻯ .Netﻗﯘﺭﯗﻟﻤﯩﺴﯩﺪﯨﻜﻰ ﺑﺎﺭﻟﯩﻖ ﺗﯩﭙﻼﺭﻧﯩﯔ ﺋﻪﺟﺪﺍﺩﻯ ﺑﻮﻟﻐﺎﻥ Objectﺗﯩﭙﺘﯩﻦ ﻣﯩﺮﺍﺱ ﻗﺎﻟﻐﺎﻥ )(GetHashCode ﻣﯧﺘﻮﺩﻯ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﯧﻠﯩﻨﯩﺪﯗ .ﺷﯘﯕﺎ ﺑﯘﻧﺪﺍﻕ ﺋﻪﮬﯟﺍﻝ ﺋﺎﺳﺘﯩﺪﺍ ﺗﯩﭙﻼﺭﻧﯩﯔ ﻣﯩﺮﺍﺱ ﺋﺎﻟﻐﺎﻥ )( GetHashCodeﯞﻩ Equalsﻣﯧﺘﻮﺩﻟﯩﺮﻧﻰ ﻗﺎﭘﻼﭖ ﻳﯧﺰﯨﺶ ) (override, 重写ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﯘﻻﺭﻧﯩﯔ ﺳﯧﺴﻠﯩﺸﺘﯘﺭﯗﻟﯘﺵ ﺧﯘﻟﻘﻠﯩﺮﯨﻨﻰ ﺋﯚﺯﮔﻪﺭﺗﯩﺸﻜﻪ ﺗﻮﻏﺮﺍ ﻛﯧﻠﯩﺪﯗ .ﺋﻪﻣﻤﺎ ﻗﯩﻤﻤﻪﺗﻠﯩﻚ) (value type,值类型ﺗﯩﭙﻼﺭﻧﻰ) int, float, structﺩﯦﮕﻪﻧﺪﻩﻙ( ﺳﯩﻠﯩﺸﺘﯘﺭﯗﺷﺘﺎ ﺋﯩﺶ ﺑﺎﺷﻘﯩﭽﯩﺮﻩﻙ ﺑﻮﻟﯩﺪﯗ .ﺋﻪﮔﻪﺭ ﺋﯩﻜﻜﯩﺴﯩﻨﯩﯔ ﻗﯩﻤﻤﯩﺘﻰ ﺋﻮﺧﺸﺎﺷﻼ ﺑﻮﻟﺴﺎ ﺋﯘﻻﺭ ﺗﻪﯕﺪﺍﺵ ﺩﻩﭖ ﻗﺎﺭﯨﻠﯩﺪﯗ. ﻳﯩﻐﯩﻨﭽﺎﻗﻠﯩﻐﺎﻧﺪﺍ Linqﺩﯨﻜﻰ ﺑﺎﺭﻟﯩﻖ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺷﻼﺭ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻗﺎﺋﯩﺪﯨﮕﻪ ﭼﯜﺷﯩﺪﯗ، ﺷﯘﯕﺎ ﻧﻪﺗﯩﺠﻪ ﺋﻮﻳﻠﯩﻐﺎﻥ ﻳﯧﺮﯨﯖﯩﺰﺩﯨﻦ ﭼﯩﻘﻤﺎﻱ ﻗﺎﻟﯩﺪﯨﻐﺎﻥ ﺋﯩﺸﻼﺭﺩﯨﻦ ﺧﺎﻟﻰ ﺑﻮﻻﻟﻤﺎﻳﺴﯩﺰ. ﻣﯘﺷﯘﻧﺪﺍﻕ ﻣﻪﺳﯩﻠﯩﻠﻪﺭﻧﯩﯔ ﺋﺎﻟﺪﯨﻨﻰ ﺋﯧﻠﯩﺶ ﺋﯜﭼﯜﻥ ،ﺋﯚﺯﯨﯖﯩﺰﻧﯩﯔ ﺷﻪﺧﺸﻰ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭙﻠﯩﺮﯨﻐﺎ ) Orderﺩﻩﻙ( ﺋﺎﻣﺎﻝ ﺑﺎﺭ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺵ ﺧﯘﻟﻘﻠﯩﺮﯨﻨﻰ ﻗﻮﺷﯘﯓ .ﻳﺎﻛﻰ ﻛﯚﭖ ﻗﯩﺴﯩﻢ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﻻ ﺗﻪﺷﻪﺑﺒﯘﺱ ﻗﯩﻠﻐﺎﻧﺪﻩﻙ classﻧﯩﯔ ﺋﻮﺭﻧﯩﻐﺎ structﺩﻩﻙ ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﺗﯩﭙﻠﯩﻖ ﮬﺎﺳﯩﻼﺕ ﺗﯩﭙﻼﺭﻧﻰ ﺋﯩﺸﻠﯩﺘﯩﯔ. ﺩﯦﻤﻪﻙ ﻗﻮﺷﯘﻣﭽﻪ ﺳﺎﯞﺍﺕ 1ﺋﯧﻴﺘﯩﭗ ﺋﯚﺗﻜﻪﻥ ﺋﯘﺳﯘﻟﯩﻤﯩﺰ ﺑﻮﻳﯩﭽﻪ ﺯﺍﻛﺎﺯ) (Orderﺗﯩﭙﯩﻨﯩﯔ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺵ ﺧﯘﻟﻘﯩﻨﻰ ﺋﯚﺯﮔﻪﺭﺗﯩﺸﻜﻪ ﺗﻮﻏﺮﺍ ﻛﻪﻟﺪﻯ .ﺋﯘﺳﯘﻟﻰ ﻣﯘﻧﺪﺍﻕ:
public class Order { public int Quantity; public bool Shipped; public string Month; public int IdProduct; )( ToStringﻣﯧﺘﻮﺩﯨﻨﻰ ﻗﺎﭘﻼﭖ ﻳﯧﺰﯨﺶ ﺋﺎﺭﻗﯩﻠﯩﻖ ،ﻣﻪﺯﻛﯘﺭ ﺗﯩﭙﻨﯩﯔ ﺋﯩﺴﯩﻤﯩﻐﺎ ﯞﻩﻛﯩﻠﻠﯩﻚ ﻗﯩﻠﯩﺪﯨﻐﺎﻥ // ﮬﻪﺭﭖ-ﺑﻪﻟﮕﻪ ﺗﯩﺰﻣﯩﺴﯩﻨﯩﯔ ﻓﻮﺭﻣﺎﺗﯩﻨﻰ ﺋﯚﺯﮔﻪﺭﺗﻜﯩﻠﻰ ﺑﻮﻟﯩﺪﯗ//
public override string ToString() { return String.Format("{0} ‐ {1} ‐ {2} ‐ {3}", this.Quantity, this.Shipped, this.Month, this.IdProduct); } public override bool Equals(object obj) { if (!(obj is Order)) return false;
58
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
else { Order o = (Order)obj; return(o.IdProduct == this.IdProduct && o.Month == this.Month && o.Quantity == this.Quantity && o.Shipped == this.Shipped); } } public override int GetHashCode() { return String.Format("{0}|{1}|{2}|{3}", this.IdProduct, this.Month, this.Quantity, this.Shipped).GetHashCode(); } } ﻳﯘﻗﯩﺮﯨﻘﯩﺪﻩﻙ ﻣﻪﺳﯩﻠﯩﻨﻰ ﮬﻪﻝ ﻗﯩﻠﯩﺸﻨﯩﯔ ﻳﻪﻧﻪ ﺑﯩﺮ ﭼﺎﺭﯨﺴﻰ Distinct ،ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯔ ﺋﯩﻜﻜﯩﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﻰ ﺑﻮﻳﯩﭽﻪ ،ﺋﯚﺯﯨﻤﯩﺰ ﺗﯜﺯﯛﯞﺍﻟﻐﺎﻥ ﺳﯧﻠﯩﺸﺘﯘﺭﻏﯘﭼﻨﻰ ﭘﺎﺭﺍﻣﯧﺘﯩﺮ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻳﻮﻟﻼﭖ ﺑﯧـﺮﯨﺶ. ﺋــﯜﭼﯩﻨﭽﻰ ﺧﯩــﻞ ﺋﯘﺳــﯘﻟﻰ ،ﻳﻪﻧــﻰ ﺋﻪﯓ ﺋــﺎﺧﯩﺮﻗﻰ ﺋﯘﺳــﯘﻟﻰ ﺑﻮﻟــﺴﺎ Orderﺗﯩﭙﯩﻨــﻰ ﻗﯩﻤﻤﻪﺗﻠﯩــﻚ ﺗﯩﭙﻘــﺎ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ .ﺩﯦﻤﻪﻛﭽﻰ Order ،ﺗﯩﭙﯩﻨﻰ classﺋﻪﻣﻪﺱ structﺗﯩﭙﻠﯩﻖ ﻗﯩﻠﯩﺶ .ﻣﻪﺳﯩﻠﻪﻥ: structﺑﻮﻟﺴﺎ ﻗﯩﻤﻤﻪﺕ ﺗﯩﭙﻠﯩﻖ ﮬﺎﺳﯩﻠﻪ ﺗﯩﭗ//
public struct Order { public int Quantity; public bool Shipped; public string Month; public int IdProduct; } ﺷﯘﻧﯩﺴﻰ ﺋﯧﺴﯩﯖﯩﺰﺩﻩ ﺗﯘﺭﺳﯘﻥ C#3.0 ،ﺩﯨﻜﻰ ﺑﺎﺭﻟﯩﻖ ﻧﺎﻣﺴﯩﺰ ﺗﯩﭙﻼﺭ ﺑﯩﺮﺩﻩﻙ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭙﻘﺎ ﺗﻪﯞﻩ. ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ Intersectﺑﯩﻠﻪﻥ Exceptﻧﻰ ﺋﯩﺸﻠﯩﺘﯩﺸﺘﯩﻦ ﻣﯩﺴﺎﻝ: ﻛﻮﺩ 4.27
var expr1 = customers[1].Orders.Intersect(customers[2].Orders); var expr2 = customers[1].Orders.Except(customers[2].Orders); Intersectﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﻰ ﺋﯩﻜﻜـــﻰ ﺗﯩﺰﻣﯩـــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﯩـــﯔ ﻛﻪﺳﻤﯩـــﺴﯩﻨﻰ ﺋﺎﻟﯩـــﺪﯗ ،ﻳﻪﻧـــﻰ ،ﮬﻪﺭ ﺋﯩﻜﻜﯩﻠﯩﺴﯩﺪﺍ ﺑﻮﻟﻐﺎﻧﻠﯩﺮﯨﻨﻰ. ) Exceptﺩﯨـــﻦ ﺑﺎﺷـــﻘﺎ( ﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﻰ ﺑﻮﻟـــﺴﺎ ،ﺑﯩﺮﯨﻨﭽـــﻰ ﺗﯩﺰﻣﯩـــﺪﯨﻜﻰ ﺋﯩﻜﻜﯩﻨﭽـــﻰ ﺗﯩﺰﻣﯩـــﺪﺍ ﺋﯘﭼﺮﯨﻤﺎﻳﺪﯨﻐﺎﻥ ﺋﻪﺯﺍﻻﺭﻧﻰ ﺋﺎﻟﯩﺪﯗ. ﺑﯘﻻﺭﻏﯩﻤﯘ ﺗﻪﯕﺪﺍﺵ ﺑﻮﻟﻐﺎﻥ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺧﺎﺱ ﺳﯚﺯﻟﯩﺮﯨﻨﯩﯔ ﻳﻮﻗﻠﯩﻘﯩﻨﻰ ﺩﯦﮕﯩﻢ ﻛﻪﻟﻤﻪﻳﯟﺍﺗﯩﺪﯗ .ﺑﯩﺮﺍﻕ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺋﺎﺭﻻﺷﺘﯘﺭﯗﭖ ﺋﯩﺸﻠﯩﺘﻪﻟﻪﻳﻤﯩﺰ:
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
4.28 ﻛﻮﺩ
var expr = (from c in customers from o in c.Orders where c.Country == Countries.Italy select o ).Intersect( from c in customers from o in c.Orders where c.Country == Countries.USA select o);
( ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﺟﻪﻣﻠﻪﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯAggregate ﺑﯘﻧﯩـﯔLinq .ﺑﻪﺯﯨﺪﻩ ﺗﯩﺰﻣﯩـﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻏـﺎ ﻧﯩـﺴﺒﻪﺗﻪﻥ ﮬﯧـﺴﺎﺑﻼﺵ ﺋﯧﻠﯩـﭗ ﺑﯧـﺮﯨﺶ ﺗـﻮﻏﺮﺍ ﻛﯧﻠﯩـﺪﯗ ﻣﻪﺷـﻐﯘﻻﺗﭽﯩﻠﯩﺮﯨﺪﯨﻦ ﺗﻪﺷـﻜﯩﻞ ﺗﺎﭘﻘـﺎﻥCount, LongCount, Sum, Min, Average ﺋﯜﭼـﯜﻥ ﺑﯘﻻﺭﻧﯩــﯔ ﻛــﯚﭖ ﻗﯩــﺴﯩﻤﻠﯩﺮﯨﻨﯩﯔ ﻗﯩﻠﯩــﺪﯨﻐﺎﻥ.ﺟﻪﻣــﻠﻪﺵ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﺎﺋﯩﻠﯩــﺴﯩﻨﻰ ﺗﻪﻣﯩــﻨﻠﯩﮕﻪﻥ .( ﭼﯜﺷﯜﻧﯜﺵ ﺗﻪﺳﻜﻪ ﺗﻮﺧﺘﯩﻤﺎﻳﺪﯗbehavior)ﺋﯩﺸﻰ ﻣﯘﺭﻩﻛﻜﻪﭖ ﺑﻮﻟﻤﯩﻐﺎﭼﻘﺎ ﺧﯘﻟﻘﻠﯩﺮﯨﻨﻰ
ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰLongCount ﯞﻩCount : ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﻰ ﺯﺍﻛﺎﺯ ﺗﯩﺰﻣﯩﺴﯩﻐﺎ ﻗﺎﺭﺗﺎ ﺋﯩﺸﻠﯩﺘﯩﺸﺘﯩﻦ ﻣﯩﺴﺎﻝCount ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ 4.29 ﻛﻮﺩ
var expr = from c in customers select new {c.Name, c.City, c.Country, OrdersCount = c.Orders.Count() }; foreach (var v in query) Console.WriteLine("{0}‐{1}‐{2}‐{3}", v.Name, v.City, v.Country, v.OrderCount); :ﺋﯩﺠﺮﺍ ﻧﻪﺗﯩﺠﯩﺴﻰ
Paolo-Brescia-Italy-2 Marco-Torino-Italy-2 James-Dallas-USA-1 Frank-Seattle-USA-1
59
60
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻳـﯘﻗﯩﺮﯨﻘﻰ ﭘﺮﻭﮔﺮﺍﻣﻤﯩـﺪﯨﻦ ﮬﺎﺳـﯩﻞ ﺑﻮﻟﻐـﺎﻥ ﻧﺎﻣـﺴﯩﺰ ﺗﯩﭙﻠﯩـﻖ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩـﯔ OrdersCountﻧـﺎﻣﻠﯩﻖ ﺧﺎﺳﻠﯩﻘﯩﻨﯩﯔ ﻗﯩﻤﻤﯩﺘﻰ ﻣـﺎﺱ ﺧﯧﺮﯨـﺪﺍﺭﻧﯩﯔ ﺯﺍﻛـﺎﺯ ﺳـﺎﻧﯩﻨﻰ ﺋﺎﻟﯩـﺪﯗ .ﺩﯦـﻤﻪﻙ Count ،ﻣﻪﺷﻐﯘﻻﺗﭽﯩـﺴﻰ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣــﺎ ﺋﯩﭽﯩــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﯩــﯔ ﺳــﺎﻧﯩﻨﻰ
int
ﺷــﻪﻛﻠﯩﺪﻩ ﻗــﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﯨــﺪﯗCount .
ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﯩﻨﯩﯔ ﻳﻪﻧﻪ ﺑﯩــﺮ ﺧﯩــﻞ ﺋﻪﻧﺪﯨﺰﯨــﺴﻰ ﺑﻮﻟــﯘﭖ ،ﺋــﯘ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﻣﻪﻟــﯘﻡ ﺷــﻪﺭﺗﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﮔﻪﻥ ﺋﻪﺯﺍﻻﺭ ﺳﺎﻧﯩﻨﻰ ﺗﯧﭙﯩﭗ ﺑﯧﺮﯨﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ :ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﺋﺎﺭﯨـﺴﯩﺪﺍ ﺯﺍﻛﺎﺯﻧﯩـﯔ ﺳـﺎﻧﻰ ﺋﯩﻜﻜﯩﮕﻪ ﺗﻪﯓ ﺑﻮﻟﻐﺎﻧﻼﺭﻧﯩﯔ ﺳﺎﻧﯩﻨﻰ ﺗﯧﭙﯩﭗ ﺑﺎﻗﺎﻳﻠﻰ:
;)int equalTwo = customers.Count(c => c.Orders.Count() == 2 Console.WrieteLine(equalTwo.ToString()); LongCountﻧﯩــﯔ ﺋﯩﻘﺘﯩــﺪﺍﺭﻯ Countﺑﯩــﻠﻪﻥ ﺋﻮﺧــﺸﺎﺵ ﺑﻮﻟــﯘﭖ ،ﻗﺎﻳﺘﯘﺭﯨــﺪﯨﻐﺎﻥ ﻗﯩﻤﻤﯩﺘــﻰ long ﺗﯩﭙﻠﯩﻖ ،ﺧﺎﻻﺱ long) .ﺗﯩﭙﻨﯩﯔ ﺳﯩﻐﯩﻤﻰ intﺩﯨﻦ ﻳﯘﻗﯩﺮﻯ(
Sumﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ )ﻳﯩﻐﯩﻨﺪﺍ( ﺑﯘ ﻣﻪﺷﻐﯘﻻﺗﭽﻰ ﺳﻪﻝ ﺋﺎﻻﮬﯩﺪﯨﺮﻩﻙ .ﺋﺎﯞﺍﻝ ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﯨﻨﻰ ﻛﯚﺭﯛﭖ ﺋﯚﺗﻪﻳﻠﻰ:
public static Numeric Sum( this IEnumerable source); public static Numeric Sum( this IEnumerable source, ;) Func selector ﺋﯘﻧﯩــﯔ ﻗﺎﻳﺘﻤــﺎ ﻗﯩﻤﻤﯩﺘــﻰ ﻳــﺎﻛﻰ ﺋﯩﻜﻜﯩﻨﭽــﻰ ﺋﻪﻧﺪﯨﺰﯨــﺪﯨﻜﻰ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮﻯ ﺑﻮﻟــﺴﯘﻥ ﺋﯘﻻﺭﻧﯩــﯔ ﺗﯩﭙــﻰ Numericﺋﯩﻜﻪﻥ .ﺑﯘ ﻳﻪﺭﺩﯨﻜﻰ Numericﺑﻮﻟﺴﺎ »ﺳﺎﻧﻠﯩﻖ« ﺩﯦـﮕﻪﻥ ﻣﻪﻧﯩـﺪﻩ ﺑﻮﻟـﯘﭖint, int?, ، ? long, long?, float, float?, double, double?, decimal,decimalﻻﺭﻧﯩﯔ ﺧﺎﻟﯩﻐﺎﻥ ﺑﯩﺮﯨﻨـﻰ ﻛﯚﺭﺳﯩﺘﯩﺪﯗ int .ﻏﯘ ﭘﯜﺗﯜﻥ ﺳﺎﻥ ﺗﯩﭙﻰ ،ﺋﻪﻣﯩﺴﻪ ? intﭼﯘ؟ C#2.0ﺩﯨــﻦ ﺗﺎﺭﺗﯩــﭗ ﻗﯩﻤﻤﻪﺗﻠﯩــﻚ ﺗﯩﭙﻠﯩــﻖ ﺋﯚﺯﮔﻪﺭﮔــﯜﭼﻰ ﻣﯩﻘــﺪﺍﺭﻻﺭﻏﺎ ﮬﯩــﭻ ﻗﺎﻧــﺪﺍﻕ ﻗﯩﻤــﻤﻪﺕ ﻳﻮﻟﻼﻧﻤﺎﻳــﺪﯨﻐﺎﻥ ﮬــﺎﻟﻪﺗﻨﻰ ﺋﯩﭙــﺎﺩﯨﻠﻪﺵ ﺯﯙﺭﯛﺭﯨﻴﯩﺘﯩــﺪﯨﻦ)ﺑﻮﻟﯘﭘﻤــﯘ ﺳــﺎﻧﺪﺍﻧﺪﯨﻜﻰ ﻗــﯘﺭﯗﻕ intﺗﯩﭙﯩﻐــﺎ ﻣﺎﺳﻼﺷﺘﯘﺭﯗﺵ( ﺷﯘ ﺗﯩﭗ ﺧﺎﺱ ﺳﯚﺯﯨﻨﯩﯔ ﺋﺎﺭﻗﯩـﺴﯩﻐﺎ ﺳـﯘﺋﺎﻝ ﺑﻪﻟﮕﯩـﺴﻰ ﺋـﺎﺭﻗﯩﻠﯩﻖ )? Tﺩﻩﻙ( ﻗـﯘﺭﯗﻕ ﺑﻮﻻﻻﻳﺪﯨﻐﺎﻥ ﺗﯩﭗ ﮬﺎﻟﯩﺘﯩﻨﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﻳﺪﯗ )ﺋﯘﻧﯩﯔ ﺗﯩﭙﻰ > .(Nullable Nullable<System.Int32ﺋﯩﭙﺎﺩﯨﻠﯩﻨﯩـﺪﯗ int? i; i=null; Console.WriteLine(i).ﺩﻩﻙ ﻳﯧـﺰﯨﺶ ﻣﯘﺗﻠﻪﻕ ﺋﯩﻨﺎﯞﻩﺗﻠﯩﻚ .ﻟﯧﻜﯩﻦ ;)int i; Console.WriteLine(i
ﺑﯘ ﻗﯘﺭﻻﺭ ﺗﻪﻛﺸﯜﺭﯛﺷﺘﯩﻦ ﺋﯚﺗﻤﻪﻳﺪﯗ.
Sumﻧﯩﯔ ﺑﯩﺮﯨﻨﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ ﺳـﺎﻧﻠﯩﻖ ﺗﯩﭙﻠﯩـﻖ ﺩﻩﭖ ﻗﺎﺭﯨﻠﯩـﭗ ﺋﯘﻻﺭﻏـﺎ ﺑﯩﯟﺍﺳﺘﻪ ﻗﻮﺷﯘﺵ ﺋﻪﻣﯩﻠﻰ ﺑﯧﺠﯩﺮﯨﭗ ﻳﯩﻐﯩﻨﺪﯨﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ .ﺋﻪﮔﻪﺭ ﻣﻪﻧﺒﻪ ﻗﯘﺭﯗﻕ ﺑﻮﻟﺴﺎ ﻧـﯚﻝ ﻗﺎﻳﺘﯩـﺪﯗ. ﺋﻪﮔﻪﺭ ﺋﻪﺯﺍﻻﺭ nullﺑﻮﻻﻻﻳﺪﯨﻐﺎﻥ ﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﯘﭖ ﮬﻪﻣﻤﯩﺴﯩﻨﯩﯔ ﻗﯩﻤﻤﯩﺘـﻰ nullﺑﻮﻟـﺴﺎ ﻧﻪﺗﯩﺠﯩـﺪﻩ null ﻗﺎﻳﺘﯩﺪﯗ .ﻣﻪﺯﻛﯘﺭ ﺋﻪﻧﺪﯨﺰﻩ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﻰ ﺑﯩﯟﺍﺳﺘﻪ ﻗﻮﺷﻘﯩﻠﻰ ﺑﻮﻟﯩﺪﯨﻐﺎﻥ ﺋﻪﮬﯟﺍﻝ ﺋﺎﺳـﺘﯩﺪﺍ ﺋﯩـــﺸﻠﯩﺘﯩﻠﯩﺪﯗ .ﻣﻪﺳـــﯩﻠﻪﻥ :ﻣﻪﻧـــﺒﻪ ﺗﯩﺰﻣـــﺎ ﺳـــﺎﻧﻼﺭ ﮔﯘﺭﭘﯩـــﺴﻰ ﺗﯩﭙﻠﯩـــﻖ ﺑﻮﻟـــﺴﺎ ،ﺗﯚﯞﻩﻧﺪﯨﻜﯩـــﺪﻩﻙ ﺋﯩﺸﻠﯩﺘﻪﻟﻪﻳﻤﯩﺰ:
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
int[] values = { 1, 3, 9, 29 }; int total = values.Sum(); . ﺑﻮﻟﯩﺪﯗ1+3+9+29=42 ﻧﻪﺗﯩﺠﻪ ﺋﻪﮔﻪﺭ ﺗﯩﺰﻣﺎ ﺑﯩﯟﺍﺳـﺘﻪ ﻗﻮﺷـﻘﯩﻠﻰ ﺑﻮﻟﯩـﺪﯨﻐﺎﻥ ﺳـﺎﻧﻠﯩﻖ ﺋﻪﺯﺍﻻﺭﺩﯨـﻦ ﺗﯜﺯﯛﻟﻤﯩـﺴﻪ) ﻣﻪﺳـﯩﻠﻪﻥ ﺧﯧﺮﯨـﺪﺍﺭﻻﺭ ﻧﯩﯔ ﺋﯩﻜﻜﯩﻨﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﻨﻰ ﻗﻮﻟﻠﯩﻨﯩﭗ ﺋﻪﺯﺍﻧﯩﯔ ﻗﺎﻳﺴﻰ ﺧﺎﺳﻠﯩﻘﯩﻨﻰ ﻗﻮﺷﯘﺷـﻨﻰSum ،(ﺗﯩﺰﻣﯩﺴﺪﻩﻙ : ﻣﻪﺳﯩﻠﻪﻥ.ﺑﻪﻟﮕﯩﻠﻪﭖ ﻗﻮﻳﯩﻤﯩﺰ 4.30 ﻛﻮﺩ
var customersOrders = from c in customers from o in c.Orders join p in products on o.IdProduct equals p.IdProduct select new { c.Name, OrderAmount = o.Quantity * p.Price }; var expr = from c in customers join o in customersOrders on c.Name equals o.Name into customersWithOrders select new { c.Name, TotalAmount = customersWithOrders.Sum(o => o.OrderAmount) }; ، ﺗﯩﺰﻣﯩــﺴﻰ ﺑﯩــﻠﻪﻥ ﮬﻪﻣــﺪﻩﻣﻠﻪﭖcustomersOrders ﺗﯩﺰﻣﯩــﺴﯩﻨﻰcustomers ﺋﯜﺳــﺘﯩﺪﯨﻜﻰ ﻣﯩــﺴﺎﻟﺪﺍ .ﮬﻪﺭﺑﯩﺮ ﺧﯧﺮﯨﺪﺍﺭﻧﯩﯔ ﺯﺍﻛﺎﺯ ﺳﺎﻧﯩﻐﺎ ﺋﯧﺮﯨﺸﯩﭗ ﺋﯘﻻﺭﻧﻰ ﻗﻮﺷﯘﺵ ﻧﻪﺗﯩﺠﯩﺴﯩﻨﻰ ﺋﺎﻟﺪﯗﻕ :ﺋﺎﺩﻩﺗﺘﻪ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩﻧﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺋﯩﭙﺎﺩﯨﻠﻪﻳﻤﯩﺰ 4.31 ﻛﻮﺩ
var expr = from c in customers join o in ( from c in customers from o in c.Orders join p in products on o.IdProduct equals p.IdProduct select new { c.Name, OrderAmount = o.Quantity * p.Price } ) on c.Name equals o.Name
61
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
into customersWithOrders select new { c.Name, TotalAmount = customersWithOrders.Sum(o => o.OrderAmount) };
ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﺴﻰLinq vs. SQL ﭼـﯜﻧﻜﻰ ﺋـﯘﻻﺭ، ﺋﯩﻜﻜﯩﺴﯩﻨﻰ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﭖ ﺑﯧﻘﯩﺸﻨﻰ ﺗﻮﻏﺮﺍ ﺗﺎﭘﺘﯩﻢ،ﻳﯧﺰﯨﭗ ﻣﯘﺷﯘ ﻳﻪﺭﮔﻪ ﻛﻪﻟﮕﻪﻧﺪﻩ ﺑــﻮ ﺗﻮﻏﺮﯨﻠﯩــﻖ.ﺋﻮﺧﺸﯩــﺸﯩﭗ ﻛﯧﺘﯩﺪﯨﻐﺎﻧــﺪﻩﻙ ﺗﯘﺭﺳــﯩﻤﯘ ﺋﺎﺭﯨــﺴﯩﺪﺍ ﺋﯩﻨﺘــﺎﻳﯩﻦ ﻣــﯘﮬﯩﻢ ﭘﻪﺭﻕ ﺑــﺎﺭ .ﺗﻮﺧﺘﯩﻠﯩﺸﻨﯩﯔ ﮬﺎﺟﯩﺘﻰ ﺑﺎﺭ ﺩﻩﭖ ﺋﻮﻳﻠﯩﺪﯨﻢ . ﺋﯩﭙﺎﺩﯨـﺴﻰSql ﺩﯨﻜﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﮕﻪ ﺋﻮﺧﺸﺎﭖ ﻛﯧﺘﯩـﺪﯨﻐﺎﻥ4.31 ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ ﻛﻮﺩ :(ﺑﯩﺮ ﺩﻩﭖ ﭘﻪﺭﻩﺯ ﻗﯩﻠﯩﻨﺪﻯ-)ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ﺋﯩﺴﯩﻤﻰ ﺑﯩﺮﺩﯨﻦ
SELECT c.Name, SUM(o.OrderAmount) AS OrderAmount FROM customers AS c INNER JOIN ( SELECT c.Name, o.Quantity * p.Price AS OrderAmount FROM customers AS c INNER JOIN orders AS o ON c.Name = o.Name INNER JOIN products AS p ON o.IdProduct = p.IdProduct ) AS o ON c.Name = o.Name GROUP BY c.Name ﺋﻪﻣﻪﻟﯩﻴﻪﺗـﺘﻪ.! ﺟﯜﻣﻠﯩﻠﯩﺮﯨﻨﯩﯔ ﻧﻪﻗﻪﺩﻩﺭ ﻛﯧﻠﻪﯕﺴﯩﺰ ﺋﯩﻜﻪﻧﻠﯩﻜﯩﻨﻰ ﮬﯧﺲ ﻗﯩﻠﻐﺎﻧـﺴﯩﺰSql ﻳﯘﻗﯩﺮﯨﻘﻰ : ﺋﯩﭙﺎﺩﯨﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﻮﺧﺸﺎﺵ ﻧﻪﺗﯩﺠﯩﮕﻪ ﺋﯧﺮﯨﺸﻪﻟﻪﻳﻤﯩﺰSql ﺋﯘﻧﯩﺪﯨﻦ ﺋﺎﺩﺩﯨﺮﺍﻕ
SELECT c.Name, SUM(o.OrderAmount) AS OrderAmount FROM customers AS c INNER JOIN ( SELECT o.Name, o.Quantity * p.Price AS OrderAmount FROM orders AS o INNER JOIN products AS p ON o.IdProduct = p.IdProduct ) AS o ON c.Name = o.Name GROUP BY c.Name : ﺗﯧﺨﯩﻤﯘ ﺋﺎﺩﺩﻯ ﺋﯩﭙﺎﺩﯨﻠﯩﻴﻪﻟﻪﻳﻤﯩﺰ،ﻟﯧﻜﯩﻦ ﺗﯧﺨﯩﻤﯘ ﻗﯩﺴﺎ
SELECT c.Name, SUM(o.Quantity * p.Price) AS OrderAmount FROM customers AS c
62
63
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
INNER JOIN orders AS o ON c.Name = o.Name INNER JOIN products AS p ON o.IdProduct = p.IdProduct GROUP BY c.Name ﺋﻪﮔﻪﺭ ﺑﯩﺰ ﺋﯜﭼﯩﻨﭽﻰ ﺧﯩﻞ Sqlﭼﻪ ﺋﯩﭙﺎﺩﯨﻠﻪﺵ ﺋﯘﺳﯘﻟﯩﻨﻰ Linqﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﺪﻩ
ﺋﯩﭙﺎﺩﯨﻠﯩﻤﻪﻛﭽﻰ ﺑﻮﻟﺴﺎﻕ ﺑﯩﺮ ﻗﯩﺴﯩﻢ ﻗﯧﻴﯩﻨﭽﯩﻠﯩﻘﻼﺭﻏﺎ ﺩﯗﭺ ﻛﯧﻠﯩﺸﯩﻤﯩﺰ ﻣﯘﻣﻜﯩﻦ .ﺳﻪﯞﻩﺑﻰSql ، ﺑﻮﻟﺴﺎ ﺋﯘﭼﯘﺭﻻﺭﻧﻰ ﻣﯘﻧﺎﺳﯩﯟﯨﺘﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺳﯜﺭﯛﺷﺘﯜﺭﯨﺪﯗ ،ﺑﺎﺭﻟﯩﻖ ﺋﯘﭼﯘﺭﻻ ﺗﺎﻛﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻟﮕﻪﻧﮕﻪ ﻗﻪﺩﻩﺭ ﺗﻪﻛﺸﻰ ﮬﺎﻟﻪﺗﺘﻪ)ﺟﻪﺩﯞﻩﻟﺪﻩ( ﺗﯘﺭﯨﺪﯨﻐﺎﻥ ﺑﻮﻟﯘﭖ ﺋﯘﻻﺭ ﺋﺎﺭﯨﺴﯩﺪﺍ ﺩﻩﺭﯨﺠﻪ ،ﻳﻪﻧﻰ ﺗﻪﯞﻩﻟﯩﻚ ﻣﯘﻧﺎﺳﯩﯟﯨﺘﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﻧﻤﻪﻳﺪﯗ .ﺑﯩﺮﺍﻕ Linqﺑﻮﻟﺴﺎ ﺧﯘﺩﺩﻯ ﺧﯧﺮﯨﺪﺍﺭ\ﺯﺍﻛﺎﺯﻻﺭ\ﻣﻪﮬﺴﯘﻻﺗﻼﺭ ﻏﺎ ﺋﻮﺧﺸﺎﺵ ﻳﻪﺭﻟﯩﻚ ﺩﻩﺭﯨﺠﻪ ،ﻳﻪﻧﻰ ﺗﻪﯞﻩﻟﯩﻚ ﻣﯘﻧﺎﺳﯩﯟﯦﺘﻰ ﺑﻮﻟﻐﺎﻥ ﺋﯘﭼﯘﺭﻻﺭﻏﺎ ﻣﻪﺷﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﺎﺭﯨﺪﯗ .ﺑﯘ ﭘﻪﺭﻕ ﺋﯩﻜﻜﻰ ﺧﯩﻞ ﺋﯘﺳﯘﻟﻨﯩﯔ ﺋﻮﺧﺸﯩﻤﯩﻐﺎﻥ ﺷﺎﺭﺍﺋﯩﺘﺘﺎ ﺋﯚﺯﯨﮕﻪ ﺧﺎﺱ ﺋﺎﺭﺗﯘﻗﭽﯩﻠﯩﻘﯩﻨﯩﯔ ﺑﺎﺭﻟﯩﻘﯩﻨﻰ ﭼﯜﺷﻪﻧﺪﯛﺭﯨﺪﯗ .ﻳﻪﻧﻰ ﺋﺎﺭﺗﯘﻗﭽﯩﻠﯩﻘﻰ ﺳﯩﺰﻧﯩﯔ ﻗﺎﻧﺪﺍﻕ ﺋﯘﭼﯘﺭﻏﺎ ﻗﺎﻧﺪﺍﻕ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﺵ ﺋﯧﻠﯩﭗ ﺑﺎﺭﯨﺪﯨﻐﺎﻧﻠﯩﻘﯩﯖﯩﺰ ﺗﻪﺭﯨﭙﯩﺪﯨﻦ ﺑﻪﻟﮕﯩﻠﯩﻨﯩﺪﯗ. ﻳﯘﻗﯩﺮﯨﻘﻰ ﺳﻪﯞﻩﺑﻠﻪﺭ ﺗﯜﭘﻪﻳﻠﻰ ﺋﻮﺧﺸﺎﺵ ﻣﻪﻧﺒﻪﺩﯨﻦ ﺋﻮﺧﺸﺎﺵ ﻧﻪﺗﯩﺠﯩﮕﻪ ﺋﯧﺮﯨﺸﯩﺪﯨﻐﺎﻥ ﺧﯩﻞ)ﺋﻪﯓ ﻳﺎﺧﺸﯩﻼﻧﻐﯩﻨﻰ( ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ Sqlﺑﯩﻠﻪﻥ Linqﺩﺍ ﭘﻪﺭﻗﻠﯩﻖ ﻳﯧﺰﯨﻠﯩﺪﯗ.
Min and Max ﺟﻪﻣﻠﻪﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﯩﭽﯩﺪﯨﻜﻰ Maxﺑﯩﻠﻪﻥ Minﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﺎ ﺋﯩﭽﯩﺪﯨﻜﻰ ﺋﻪﯓ ﭼﻮﯓ ﯞﻩ ﺋﻪﯓ ﻛﯩﭽﯩﻚ ﺋﻪﺯﺍﻧﻰ ﺗﯧﭙﯩﺸﻘﺎ ﺋﯩﺸﻠﺘﯩﻠﯩﺪﯗ .ﺋﯘﻻﺭﻣﯘ ﺑﯩﺮﻗﺎﻧﭽﻪ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﻠﻪﻧﮕﻪﻥ:
public static Numeric Min/Max( this IEnumerable source); public static T Min/Max( this IEnumerable source); public static Numeric Min/Max( this IEnumerable source, Func selector); public static S Min/Max( this IEnumerable source, Func selector); ﺑﯩﺮﯨﻨﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﺋﻪﺯﺍﻻﺭﻏﺎ ﻧﯩـﺴﺒﻪﺗﻪﻥ ﺋـﺎﺭﺧﯩﻤﯩﺘﯩﻜﯩﻠﯩﻖ ﺳﯧﻠﯩـﺸﺘﯘﺭﯗﺵ ﺋﯧﻠﯩـﭗ ﺑﺎﺭﯨـﺪﯗ .ﺷـﯘﯕﺎ ﻣﻪﺯﻛﯘﺭ ﺋﻪﻧﺪﯨﺰﯨﻨﻰ ﺋﻪﺯﺍﻟﯧﺮﻯ ﺳـﺎﻥ ﺑﻮﻟﻐـﺎﻥ ﺗﯩﺰﻣﻼﺭﻏـﺎ ﺋﯩـﺸﻠﯩﺘﯩﺶ ﻣﯘﯞﺍﭘﯩـﻖ .ﻣﻪﺳـﯩﻠﻪﻥ :ﺗﯚﯞﻩﻧـﺪﯨﻜﻰ ﻣﯩﺴﺎﻟﺪﺍ ﺑﺎﺭﻟﯩﻖ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ﺑﺎﺭﻟﯩﻖ ﺯﺍﻛﺎﺯﻟﯩﺮﯨﻨﯩﯔ ﻣﯩﻘـﺪﺍﺭﯨﻐﺎ ﻧﯩـﺴﺒﻪﺗﻪﻥ ﺋﻪﯓ ﻛﯩﭽﯩﻜﯩﻨـﻰ ﺗﯧـﭙﯩﺶ ﻣﻪﺷﻐﯘﻻﺗﻰ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﯩﺪﯗ:
64
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﻮﺩ 4.32
var expr = (from c in customers from o in c.Orders select o.Quantity ).Min(); ﺋﯩﻜﻜﯩﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﯨﺪﻩ ﺋﻪﺯﺍﻻﺭﻧﯩـﯔ ﺗﯩﭙﯩﻨـﻰ ﺋﯧﺘﯩﯟﺍﺭﻏـﺎ ﺋﺎﻟﻤـﺎﻱ ﭼـﻮﯓ -ﻛﯩﭽﯩﻜﯩﻨـﻰ ﺗﺎﭘﯩـﺪﯗ. )ﺋﻪﻟﯟﻩﺗﺘﻪ ،ﭼﻮﯓ -ﻛﯩﭽﯩﻜﯩﻨﻰ ﺗﯧﭙﯩﺶ ﺋﯜﭼﯜﻥ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺵ ﺋﯧﻠﯩـﭗ ﺑﯧـﺮﯨﺶ ﻛﯧـﺮﻩﻙ( ﺋﻪﮔﻪﺭ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﺋﻪﺯﺍ ﺗﯩﭙــﻰ > IComparable
var expr = (from c in customers from o in c.Orders select new { o.Quantity} ).Min(); ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺴﻰ ﻗﯘﺭﯗﻕ ﻳـﺎﻛﻰ ﺑـﺎﺭﻟﯩﻖ ﺋﻪﺯﺍﻻﺭﻧﯩـﯔ ﻗﯩﻤﻤﯩﺘـﻰ nullﺑﻮﻟـﯘﭖ ﻗﺎﻟﻐـﺎﻥ ﺋﻪﮬـﯟﺍﻝ ﺋﺎﺳـﺘﯩﺪﺍ، ﺋﻪﮔﻪﺭ ﺋﻪﻧﺪﯨﺰﯨــﺪﯨﻜﻰ Numericﺗﯩﭙــﻰ ﻗــﯘﺭﯗﻕ ﺑﻮﻻﻻﻳــﺪﯨﻐﺎﻥ ﺗﯩــﭗ ﺑﻮﻟــﺴﺎ ،ﻧﻪﺗﯩــﺠﻪ nullﺑﻮﻟﯩــﺪﯗ. ﺋﯘﻧﺪﺍﻕ ﺑﻮﻟﻤﺎﻳﺪﯨﻜﻪﻥ ArgumentNullException ،ﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﻗﻮﻳﯘﭖ ﺑﯧﺮﯨﻠﯩﺪﯗ .ﺋـﺎﺧﯩﺮﻗﻰ ﺋﯩﻜﻜــﻰ ﺧﯩــﻞ ﺋﻪﻧﺰﯨــﺪﯨﻜﻰ ﺗــﺎﻟﻼﺵ ﻛﯚﺭﺳﻪﺗﻤﯩــﺴﻰ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﺯﺍ ﺋﯩﭽﯩــﺪﯨﻜﻰ ﻗﺎﻳــﺴﻰ ﺧﺎﺳــﻠﯩﻘﻨﻰ ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﺷﻨﻰ ﺑﻪﻟﮕﯩــﻠﻪﭖ ﺑﯧﺮﯨــﭗ ﻳﯘﻗﯩﺮﯨﻘﯩــﺪﻩﻙ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻘﻨﯩــﯔ ﺋﺎﻟــﺪﯨﻨﻰ ﺋــﺎﻟﻐﯩﻠﯩﻤﯘ ﺑﻮﻟﯩــﺪﯗ. ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 4.34ﻗﯩﻤﻤﻪﺕ ﺗﺎﻟﻠﯩﻐﯘﭺ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺧﯧﺮﯨﺪﺍﺭ ﺗﯩﭙﯩﻠﯩﺮﯨﻐﺎ ﻧﯩﺴﺒﻪﺗﻪﻥ Maxﻣﻪﺷﻐﯘﻻﺗﻰ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﺶ
var expr = (from c in customers from o in c.Orders select new { o.Quantity} ;)).Min(o => o.Quantity
65
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
Averageﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﻣﻪﺯﻛﯘﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﻰ ﺋﻪﺯﺍ ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻧﯩﯔ ﺋﻮﺗﺘﯘﺭﭼﻪ ﻗﯩﻤﻤﯩﺘﯩﻨﻰ ﺗﺎﭘﯩﺪﯗ .ﺋﯘ ﺋﺎﻟﺪﯨﺪﺍ ﺳﯚﺯﻟﯩﮕﻪﻥ Max, Min, Sumﻻﺭﻏــﺎ ﺋﻮﺧــﺸﺎﺵ ﺋﻪﺯﺍﻻﺭﻧﯩــﯔ ﻗﯩﻤﻤﻪﺗﻠﯩــﻚ ﺗﯩــﭗ ﺑﻮﻟﻐــﺎﻥ ﮬــﺎﻟﯩﺘﯩﮕﻪ ﻣﯘﯞﺍﭘﯩــﻖ .ﺋﯘﻧــﺪﺍﻕ ﺑﻮﻟﻤﯩﻐــﺎﻥ ﺋﻪﮬــﯟﺍﻝ ﺋﺎﺳــﺘﯩﺪﺍ ﺑﺎﺷــﻘﺎ ﺋﻪﻧــﺪﯨﺰﯨﻠﯩﺮﻯ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﻛــﯚﭖ ﺧﺎﺳــﻠﯩﻖ ﭼﺎﻗﯩﺮﯨﻠﻤــﺎ ﺗﯩﭙﻨﯩــﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﺧﺎﺳﻠﯩﻘﯩﻨﻰ ﺑﻪﻟﮕﯩﻠﻪﭖ ﻗﻮﻳﯘﺵ ﻛﯧـﺮﻩﻙ .ﺷـﯘﻧﺪﯨﻼ ﻧﻮﺭﻣـﺎﻝ ﻣﻪﺷـﻐﯘﻻﺕ ﺋﯧﻠﯩـﭗ ﺑﺎﺭﺍﻻﻳـﺪﯗ. ﺋﯘﻧﯩﯔ ﺗﯚﯞﻩﻧﺪﻩ ﻛﯚﺭﺳﯩﺘﯩﻠﮕﻪﻧﺪﻩﻙ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺑﺎﺭ:
public static Result Average( this IEnumerable source); public static Result Average( this IEnumerable source, ;) Func selector ﺋﻮﺗﺘﯘﺭﭼﻪ ﻗﯩﻤﻤﯩﺘﻰ ﺋﯧﻠﯩﻨﻤﺎﻗﭽﻰ ﺑﻮﻟﻐﺎﻥ Numericﺗﯩﭗ int, int?, long, long?, float, float?, double, double?, decimal, or decimal?.ﻻﺭﻧﯩﯔ ﺑﯩﺮﻯ ﺑﻮﻟﯘﺷﻰ ﻛﯧﺮﻩﻙ .ﺷﯘﻧﺪﺍﻕ ﺑﻮﻟﻐﺎﻧﺪﺍ ﻧﻪﺗﯩﺠﻪ ﻣﻪﻧﺒﻪ ﺗﯩﭙﻘﺎ ﯞﺍﺭﯨﺴﻠﯩﻖ ﻗﯩﻠﯩﭙﻼ ﻗﺎﻟﻤﺎﻱ ،ﻗﯘﺭﯗﻕ ﺑﻮﻻﻻﻳﺪﯨﻐﺎﻥ ﺋﺎﻻﮬﯩﺪﯨﻠﯧﻜﯩﻨﯩﻤﯘ ﺳﺎﻗﻼﭖ ﻗﺎﻟﯩﺪﯗ. ﺋﯘﻧﯩﯖﺪﯨﻦ ﺑﺎﺷﻘﺎ ،ﻣﻪﻧﺒﻪﺩﯨﻜﻰ ﺋﻪﺯﺍ intﻳﺎﻛﻰ longﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﺴﺎ ،ﻧﻪﺗﯩﺠﻪ doubleﺗﯩﭙﻠﯩﻖ؛ ﻣﻪﻧﺒﻪﺩﯨﻜﻰ ﺋﻪﺯﺍ ? intﻳﺎﻛﻰ ? longﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﺴﺎ ،ﻧﻪﺗﯩﺠﻪ ? doubleﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﯩﺪﯗ. ﺑﯘﻧﺪﺍﻕ ﺑﻮﻟﯩﺸﯩﻨﻰ ﭼﯜﺷﯜﻧﯜﺵ ﺗﻪﺱ ﺋﻪﻣﻪﺱ ،ﻳﻪﻧﻰ ،ﺑﯩﺮﻗﺎﻧﭽﻪ ﭘﯜﺗﯜﻥ ﺳﺎﻧﻨﯩﯔ ﺋﻮﺗﺘﯘﺭﯨﭽﻪ ﻗﯩﻤﻤﯩﺘﻰ ﻛﻪﺳﯩﺮ ﺳﺎﻥ ﭼﯩﻘﯩﺸﻰ ﻣﯘﻣﻜﯩﻦ. ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ ﺋﯩﻜﻜﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﮕﻪ ﺑﯩﺮﺩﯨﻦ ﻣﯩﺴﺎﻝ: ﻛﻮﺩ Average 4.35ﻧﯩﯔ ﺋﯩﻜﻜﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﻰ ﻣﻪﮬﺴﯘﻻﺕ ﺑﺎﮬﺎﻟﯩﺮﯨﻐﺎ ﻣﻪﺷﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﺎﺭﯨﺪﯗ
var expr = (from p in products select p.Price ).Average(); var expr = (from p in products select new { p.Price } ).Average(p => p.Price); ﺋﯩﻜﻜﯩﻨﭽﻰ ﻣﯩﺴﺎﻟﯩﺪﯨﻜﻰ ﻛﯚﻙ ﺭﻩﯕﮕﻪ ﺑﻮﻳﺎﻟﻐـﺎﻥ ﺳﯜﺭﯛﺷـﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨـﺴﯩﻨﯩﯔ ﻧﻪﺗﯩﺠﯩـﺴﯩﮕﻪ Average ﻧﯩﯔ ﺋﯩﻜﻜﯩﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﺸﺘﯩﻜﻰ ﺳﻪﯞﻩﺏ ،ﺋﯘﻧﯩـﯔ ﻧﻪﺗﯩـﺠﻪ ﺗﯩﺰﻣﯩـﺴﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ ﻧﺎﻣــﺴﯩﺰ ﺗﯩﭙﻠﯩــﻖ ﺑﻮﻟﻐــﺎﻧﻠﯩﻘﻰ ﺋﯜﭼــﯜﻥ ﺋــﯘﻻﺭ ﺋﺎﺭﯨــﺴﯩﺪﺍ ﺑﯩﯟﺍﺳــﺘﻪ ﺋــﺎﺭﻓﯩﻤﯧﺘﯩﻜﯩﻠﯩﻖ ﺋﻪﻣﻪﻝ ﺑﯩﺠﯩﺮﮔﯩﻠــﻰ ﺑﻮﻟﻤﺎﻳــﺪﯗ .ﺷــﯘﯕﺎ ﭼﻮﻗــﯘﻡ ﺋﯘﻧﯩــﯔ ﻗﺎﻳــﺴﻰ ﺧﺎﺳــﻠﯩﻘﯩﻨﯩﯔ ﺋﻮﺗﺘــﯘﺭﯨﭽﻪ ﻗﯩﻤﻤﯩﺘﯩﻨــﻰ lambdaﺋﯩﭙﺎﺩﯨــﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﻪﻟﮕﯩﻠﻪﭖ ﺑﯧﺮﯨﺸﯩﻤﯩﺰ ﻛﯧﺮﻩﻙ. ﺗﯚﯞﻩﻧﺪﻩ ﺑﺎﺭﻟﯩﻖ ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﯞﻩ ﺋﯘﻻﺭﻧﯩﯔ ﺯﺍﻛـﺎﺯ ﻣﯩﻘـﺪﺍﺭﻟﯩﺮﯨﻨﯩﯔ ﺋﻮﺗﺘـﯘﺭﭼﻪ ﻗﯩﻤﻤﯩﺘﯩﻨـﻰ ﭼﯩﻘﯩﺮﯨـﺪﯨﻐﺎﻥ ﻣﯩﺴﺎﻝ ﺑﯧﺮﯨﻠﺪﻯ:
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
4.36 ﻛﻮﺩ
var expr = from c in customers join o in ( from c in customers from o in c.Orders join p in products on o.IdProduct equals p.IdProduct select new { c.Name, OrderAmount = o.Quantity * p.Price } ) on c.Name equals o.Name into customersWithOrders select new { c.Name, AverageAmount = customersWithOrders.Average(o => o.OrderAmount) }; :ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﯩﺴﺎﻟﻨﯩﯔ ﻧﻪﺗﯩﺠﯩﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺑﻮﻟﯘﺷﻰ ﻣﯘﻣﻜﯩﻦ
{Name=Paolo, AverageAmount=65} {Name=Marco, AverageAmount=350} {Name=James, AverageAmount=600} {Name=Frank, AverageAmount=1000}
66
67
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
Generationﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﻗﯘﺭﻏﯘﭺ( ﻣﻪﺳﯩﻠﻪﻥ -2000ﻳﯩﻠﯩﺪﯨﻦ -2007ﻳﯩﻠﯩﮕﯩﭽﻪ ﺑﻮﻟﻐـﺎﻥ ﺋـﺎﺭﻟﯩﻘﺘﯩﻜﻰ ﺯﺍﻛـﺎﺯﻻﺭ ﺗﯩﺰﯨﻤﻠﯧﻜﯩﻨـﻰ ﭼﯩﻘﯩـﺮﯨﺶ، ﻳﺎﻛﻰ ﺋﻮﺧﺸﺎﺵ ﺑﯩﺮ ﺋﯘﭼﯘﺭﻏﺎ ﺋﻮﺧـﺸﺎﺵ ﺑﯩـﺮ ﻣﻪﺷـﻐﯘﻻﺗﻨﻰ ﺗﻪﻛـﺮﺍﺭ ﺋﯧﻠﯩـﭗ ﺑﯧﺮﯨـﺸﺘﻪﻙ ﻣﻪﺷـﻐﯘﻻﺗﻼﺭﻧﻰ ﻗﯘﺭﻏﯘﭺ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﯩﻨﺘﺎﻳﯩﻦ ﺋﻪﭘﭽﯩﻠﻠﯩﻚ ﺑﯩﻠﻪﻥ ﺋﯧﻠﯩﭗ ﺑﺎﺭﺍﻻﻳﺪﯗ.
) Rangeﺩﺍﺋﯩﺮﻩ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( ﺋــﯘ ﺑﻪﻟﮕﯩﻠﯩــﻚ ﺩﺍﺋﯩﺮﯨــﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗــﻠﻪﺭ ﺗﯩﺰﻣﯩــﺴﻰ ﮬﺎﺳــﯩﻞ ﻗﯩﻠﯩــﭗ ﺑﯧــﺮﯨﺶ ﺭﻭﻟﯩﻐــﺎ ﺋــﯧﮕﻪ ﺑﻮﻟــﯘﭖ، ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺑﯩﺮﺩﯨﻦ -ﺑﯩﺮ ﺋﻪﻧﺪﯨﺰﯨﮕﻪ ﺋﯩﮕﻪ:
public static IEnumerable Range( int start, ;) int count ﻛﻮﺩ 4.40ﺩﺍ -2005ﻳﯩﻠﺪﯨﻦ -2007ﻳﯩﻠﻐﯩـﭽﻪ ﺋـﺎﺭﻟﯩﻘﺘﯩﻜﻰ ﺯﺍﻛـﺎﺯﻻﺭﻧﻰ ﺳـﯜﺯﯛﭖ ﺋـﯧﻠﯩﺶ ﻣﻪﺷـﻐﯘﻻﺕ ﻛﻮﺩﻯ ﺑﯧﺮﯨﻠﺪﻯ. ﺋﻪﺳــﻜﻪﺭﺗﯩﺶ :ﻣﻪﺯﻛــﯘﺭ ﻣﻪﺳــﯩﻠﯩﮕﻪ ﻧﯩــﺴﺒﻪﺗﻪﻥ whereﺧــﺎﺱ ﺳــﯚﺯﻯ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﻳﯩــﻞ ﭼﯧﻜــﻰ ﻗﻮﻳــﯘﺵ ﺋﻪﻗﯩﻠﮕﻪ ﺋﻪﯓ ﻣﯘﯞﺍﭘﯩﻖ ﺋﯘﺳﯘﻝ .ﺑﯘ ﻛـﻮﺩ ﭘﻪﻗﻪﺕ Rangeﻧﯩـﯔ ﺋﯩـﺸﻠﯩﺘﯩﺶ ﺋﯘﺳـﯘﻟﯩﻨﻰ ﭼﯜﺷـﻪﻧﺪﯛﺭﯛﺵ ﻣﻪﻗﺴﯩﺘﯩﺪﻩ ﻣﯩﺴﺎﻝ ﺋﯜﭼﯜﻧﻼ ﺑﯧﺮﯨﻠﺪﻯ ،ﻟﯧﻜﯩﻦ ﻳﺎﺧﺸﻰ ﺋﯘﺳﯘﻝ ﺑﻮﻟﯘﺷﻰ ﻧﺎﺗﺎﻳﯩﻦ. ﻛﻮﺩ -2005 4.40ﻳﯩﻠﯩﺪﯨﻦ -2007ﻳﯩﻠﮕﯩﭽﻪ ﺑﻮﻟﻐﺎﻥ ﺯﺍﻛﺎﺯﻻﺭﻏﺎ ﺋﯧﺮﯨﺸﯩﺶ
var expr = Enumerable.Range(2005, 3) .SelectMany(x => (from o in orders where o.Year == x select new { o.Year, o.Amount }));
ﻳﯘﻗﯩﺮﯨﻘﯩﻼﺭﺩﯨﻦ ﺑﺎﺷﻘﺎ Rangeﻧﻰ ﻳﻪﻧﻪ »ﻛﯘﯞﺍﺩﯨﺮﺍﺕ ﻛﯚﺗﯜﺭﯛﺵ«» ،ﮬﻪﺳﺴﯩﻠﻪﺵ« ﯞﻩ ﻓﺎﻛﺘﻮﺭﯨﻴﺎﻟﯩﻨﻰ ﮬﯧﺴﺎﺑﻼﺷﺘﻪﻙ ﺋﻮﺭﯗﻧﻼﺭﻏﯩﻤﯘ ﻗﻮﻟﻠﯩﻨﯩﺸﻘﺎ ﺑﻮﻟﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ number 4.41ﻧﯩﯔ ﭘﺎﻛﺘﯧﺮﻳﺎﻟﯩﻨﻰ Rangeﺩﯨﻦ ﭘﺎﻳﺪﯨﻠﯩﻨﯩﭗ ﺗﯧﭙﯩﺶ
static int Factorial(int number) { return (Enumerable.Range(0, number + 1) .Aggregate(0, (s, t) => t == 0 ? 1 : s *= t)); }
68
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
) Repeatﺗﻪﻛﺮﺍﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( ﻣﻪﺯﻛــﯘﺭ ﻣﻪﺷــﻐﯘﻻﺗﭽﻰ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧــﻰ ﺗﻪﻛــﺮﺍﺭﻻﭖ ﻛﯚﭘﻪﻳﺘﯩــﺪﯗ .ﺋﻪﮔﻪﺭ ﺋﻪﺯﺍ ﭼﺎﻗﯩﺮﯨﻠﻤــﺎ ﺗﯩﭙﻠﯩـــﻖ ﺑﻮﻟـــﺴﺎ ،ﮬﻪﺭ ﺑﯩـــﺮ ﺋﻪﺯﺍﻧﯩـــﯔ ﺋـــﯚﺯﻯ ﺋﻪﻣﻪﺱ ﺑﻪﻟﻜـــﻰ ﻣﯘﻧﺎﺳـــﯩﭗ ﭼﺎﻗﯩﺮﻏﯘﭼﯩـــﺴﻰ)(引用 ﺗﻪﻛﺮﺍﺭﻟﯩﻨﯩﺪﯗ. Repeatﻣﻪﺷﻐﯘﻻﺗﭽﯩــــﺴﻰ ﻛﯚﭘــــﯜﻧﭽﻪ ﺗﯩﺰﻣﯩــــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧــــﻰ ﺩﻩﺳﻠﻪﭘﻠﻪﺷــــﺘﯜﺭﯛﺵ ،ﺋﻮﺧــــﺸﺎﺵ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻛﻨﻰ ﻧﻪﭼــﭽﻪ ﻗﯧــﺘﯩﻢ ﺋﯩﺠــﺮﺍ ﻗﯩﻠﯩــﺸﺘﻪﻙ ﺋﻪﮬــﯟﺍﻟﻼﺭﺩﺍ ﺋﯩــﺸﻠﯩﺘﯩﻠﯩﺪﯗ .ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﻣﯩــﺴﺎﻟﺪﺍ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ﺋﯩﺴﯩﻤﻠﯩﺮﯨﻨﻰ ﺋﺎﻟﯩﺪﯨﻐﺎﻥ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﻰ ﺋﯜﭺ ﻗﯧﺘﯩﻢ ﺗﻪﻛﺮﺍﺭ ﺋﯩﺠﺮﺍ ﻗﯩﻠﯩﺪﯗ. ﻛﻮﺩ 4.42
ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﻰ ﺗﻪﻛﺮﺍﺭ ﺋﯩﺠﺮﺍ ﻗﯩﻠﯩﺶ
var expr = Enumerable.Repeat( (from c in customers select c.Name), 3) ;).SelectMany(x => x foreach (var v in expr) Console.WriteLine(v); ﻳــﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩﺗ ـﺎ Repeatﻧﯩــﯔ ﻧﻪﺗﯩﺠﯩــﺴﻰ ﺗﯩﺰﻣﯩﻼﺭﻧﯩــﯔ ﺗــﻮﭘﻠﯩﻤﻰ .ﺷــﯘﯕﺎ ﺋﯘﻧﯩــﯔ ﺋﯜﺳــﺘﯩﺪﻩ ﻳﻪﻧﻪ SelectManyﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﯩﻨﻰ ﻗﻮﻟﻠﯩﻨﯩـــﭗ ﺑـــﺎﺭﻟﯩﻖ ﺋﻪﺯﺍﻻﺭﻧـــﻰ ﺑﯩـــﺮ ﺗﯩﺰﻣﯩﻐـــﺎ ﺗﻪﻛـــﺸﻰ ﺭﻩﺗـــﻠﻪﭖ ﺋﻮﺭﯗﻧﻼﺷﺘﯘﺭﺩﯗﻕ. ﺋﯩﺠﺮﺍ ﻧﻪﺗﯩﺠﯩﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ:
Paolo Marco James Frank Paolo Marco James Frank Paolo Marco James Frank
69
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
) Emptyﻗﯘﺭﯗﻕ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( ﻣﻪﺯﻛﯘﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﻰ ﻣﻪﻟﯘﻡ ﺗﯩﭙﻠﯩﻖ ﺋﻪﺯﺍﻧﯩﯔ ﻗﯘﺭﯗﻕ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﻗـﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﻩﻟﻪﻳـﺪﯗ .ﻳﻪﻧـﻰ ﻗـﯘﺭﯗﻕ ﺗﯩﺰﻣﺎ ﮬﺎﺳﯩﻞ ﻗﯩﻠﯩﺸﺘﺎ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ Empty 4.43ﺩﯨﻦ ﭘﺎﻳﺪﯨﻠﯩﻨﯩﭗ ﺧﯧﺮﯨﺪﺍﺭ ﺗﯩﭙﯩﻨﯩﯔ ﻗﯘﺭﯗﻕ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﮬﺎﺳﯩﻞ ﻗﯩﻠﯩﺶ
IEnumerable customers = Enumerable.Empty();
Quantifiersﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﻣﯩﻘﺪﺍﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ( ﺗﯩﺰﻣــﺎ ﺋﯩﭽﯩــﺪﻩ ﻣﻪﻟــﯘﻡ ﺷــﻪﺭﺗﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨــﺪﯨﻐﺎﻥ ﺋﻪﺯﺍﻧﯩــﯔ ﺑــﺎﺭ -ﻳــﻮﻗﻠﯩﻘﯩﻨﻰ ﺗﻪﻛــﺸﯜﺭﯛﺷﻤﯘ ﺋﯩﮫﯩﺘﯩﻴﺎﺟﯩﯩﻤﯩﺰﻧﯩــﯔ ﺳــﯩﺮﺗﯩﺪﺍ ﺋﻪﻣﻪﺱ .ﮔﻪﺭﭼﻪ ﺑﯘﻧــﺪﺍﻕ ﻣﻪﺳــﯩﻠﯩﻠﻪﺭﻧﻰ ﺑﯩــﺰ ﺋﺎﻟــﺪﯨﻨﻘﻰ ﻣﻪﺯﻣــﯘﻧﻼﺭﺩﺍ ﺳــﯚﺯﻟﻪﭖ ﺋــﯚﺗﻜﻪﻥ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻼﺭﻧﻰ ﺑﯩﺮﻟﻪﺷــﺘﯜﺭﯛﺭﭖ ﺋﯩــﺸﻠﯩﺘﯩﺶ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﻏﯩﻠﻰ ﺑﻮﻟﯩﺴﯩﻤﯘ ،ﻟﯧﻜﯩﻦ Linqﻣﯘﺷﯘﻧﺪﺍﻕ ﺋﻪﮬﯟﺍﻟﻼﺭﻏﺎ ﺧﺎﺱ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭﻧﻰ ﺗﻪﻣﯩﻨﻠﯩﮕﻪﻥ.
Anyﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺗﻮﻧﯘﺷﺘﯘﺭﻣﺎﻗﭽﻰ ﺑﻮﻟﻐﺎﻥ ﺗـﯘﻧﺠﻰ ﻣﻪﺷـﻐﯘﻻﺗﭽﻰ Anyﺑﻮﻟـﯘﭖ ،ﺋـﯘ ﺑﯧـﺮﯨﻠﮕﻪﻥ ﺭﺍﺱ -ﻳﺎﻟﻐـﺎﻥ ﺗﯩﭙﻠﯩـﻖ ﻛﯚﺭﺳﻪﺗﻤﯩﮕﻪ ﺋﺎﺳﺎﺳﻪﻥ ﺭﺍﺱ -ﻳﺎﻟﻐﺎﻧﻠﯩﻖ ﻗﯩﻤﻤﻪﺕ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ .ﺗﯚﯞﻩﻧﺪﯨﻜﯩﻠﻪﺭ ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ:
public static bool Any( this IEnumerable source, Func predicate); public static bool Any( ;) this IEnumerable source ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﯧﺘﻮﺩ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﯨﻨﻰ ﻛـﯚﺭﮔﯩﻨﯩﯖﯩﺰﺩﻩ ،ﻛﺎﻟﻠﯩﯖﯩﺰﻏـﺎ »ﻣﻪﻧـﺒﻪﺩﯨﻦ ﺑﺎﺷـﻘﺎ ﮬﯧﭽﻘﺎﻧـﺪﺍﻕ ﺷـﻪﺭﺕ ﻗﻮﺑﯘﻝ ﻗﯩﻠﻤﺎﻳﺪﯨﻐﺎﻥ ﻣﯧﺘﻮﺩ ﺷﻪﻛﻠﻰ ﻧـﯧﻤﯩﮕﻪ ﺋﺎﺳـﺎﻥ ﺭﺍﺳـﺖ -ﻳﺎﻟﻐـﺎﻥ ﻗﯩﻤـﻤﻪﺕ ﻗﺎﻳﺘﯘﺭﯨـﺪﯗ؟« ﺩﯦـﮕﻪﻥ ﺳﯘﺋﺎﻝ ﻛﯧﻠﯩـﺸﻰ ﻣـﯘﻣﻜﯩﻦ .ﻣﻪﺯﻛـﯘﺭ ﺋﻪﻧﺪﯨﺰﯨـﺪﻩ ،ﺋﻪﮔﻪﺭ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩـﺪﺍ ﻛﻪﻡ ﺩﯦﮕﻪﻧـﺪﻩ ﺑﯩـﺮ ﺩﺍﻧﻪ ﺋﻪﺯﺍ ﺑﻮﻟــﺴﺎ ﺭﺍﺳ ـﺘﻨﻰ ،ﺋﯘﻧــﺪﺍﻕ ﺑﻮﻟﻤﯩــﺴﺎ ﻳﺎﻟﻐــﺎﻧﻨﻰ ﻗﺎﻳﺘﯘﺭﯨــﺪﯗ .ﮬﯧــﺴﺎﺑﺘﺎ ،ﻣﻪﻟــﯘﻡ ﺗﯩﺰﻣﻨﯩــﯔ ﻗــﯘﺭﯗﻕ ﻳــﺎﻛﻰ ﺋﻪﻣﻪﺳﻠﯧﻜﯩﻨﻰ ﺗﻪﻛﺸﯜﺭﯨﺪﯗ. ﺋﯩﻜﻜﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﺑﻮﻟﺴﺎ ،ﻛﯚﺭﺳﻪﺗﻤﻪ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺷﻪﺭﺕ ﻳﻮﻟﻠﯩﻨﯩﺪﯗ ،ﺋﻪﮔﻪﺭ ﺗﯩﺰﻣﯩﺪﺍ ﺋﯘﺷﺒﯘ ﺷﻪﺭﺗﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨﺪﯨﻐﺎﻥ ﺋﻪﺯﺍﺩﯨﻦ ﻛﯧﻤﯩﺪﻩ ﺑﯩﺮﺳﻰ ﺑﻮﻟﺴﺎ ﺭﺍﺳﺘﻨﻰ ،ﺑﻮﻟﻤﯩﺴﺎ ﻳﺎﻟﻐﺎﻧﻨﻰ ﻛﻪﻟﺘﯜﺭﯨﺪﯗ. ﻣﻪﺳــﯩﻠﻪﻥ :ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﻣﯩــﺴﺎﻟﺪﺍ ﺑــﺎﺭﻟﯩﻖ ﺧﯧﺮﯨــﺪﺍﻻﺭﻧﯩﯔ ﺑــﺎﺭﻟﯩﻖ ﺯﺍﻛﺎﺯﻟﯩﺮﯨﻨﯩــﯔ ﺋﯩﭽﯩــﺪﻩ ﻣﻪﮬــﺴﯘﻻﺕ ﺗﻪﺭﺗﯩــﭗ ﻧﻮﻣــﯘﺭﻯ ) 1 (idProductﮔﻪ ﺗﻪﯓ ﺑﻮﻟﻐــﺎﻥ ﻣﻪﮬــﺴﯘﻻﺗﻨﯩﯔ ﻣﻪﯞﺟــﯘﺕ ﻳــﺎﻛﻰ ﺋﻪﻣﻪﺳــﻠﯩﻜﻰ ﺗﻪﻛﺸﯜﺭﯛﻟﯩﺪﯗ.
70
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﻛﻮﺩ 4.44
bool result = (from c in customers from o in c.Orders select o) .Any(o => o.IdProduct == 1); ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻗﯘﺭﺩﺍ ﻧﻪﺗﯩﺠﯩﻨﻰ ﻗﻪﺳﺘﻪﻥ ﻳﺎﻟﻐﺎﻥ ﭼﯩﻘﺎﺭﺩﯗﻕ ،ﭼﯜﻧﻜﻰ ﺗﯩﺰﻣﺎ ﻗﯘﺭﯗﻕ//
result = Enumerable.Empty().Any(o => o.IdProduct == 1);//false ﺷﯘﻧﯩﺴﻰ ﺋﯧﺴﯩﯖﯩﺰﺩﻩ ﺑﻮﻟـﺴﯘﻥ ،ﺗﻪﻛـﺸﯜﺭﯛﺵ ﺟﻪﺭﻳﺎﻧﯩـﺪﺍ o.IdProduct == 1ﻗﺎﻧـﺎﺋﻪﺗﻠﻪﻧﮕﻪﻥ ﺯﺍﻣـﺎﻧﻼ ﺋﻮﻣﯘﻣﯩﻲ ﺋﯩﭙﺎﺩﻩ ﺋﺎﺧﯩﺮﻟﯩﺸﯩﺪﯗ.
) Allﮬﻪﻣﻤﻪ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( Allﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺗﯩﺰﻣﯩـﺪﯨﻜﻰ ﺑـﺎﺭﻟﯩﻖ ﺋﻪﺯﺍﻻﺭﻧﯩـﯔ ﺑﯧـﺮﯨﻠﮕﻪﻥ ﺷـﻪﺭﺗﻨﻰ ﻗﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨـﺪﯨﻐﺎﻥ ﻳـﺎﻛﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﻣﻪﻳﺪﯨﻐﺎﻧﻠﯩﻘﯩﻨﻰ ﺗﻪﻛﺸﯜﺭﯛﺷﻜﻪ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ .ﺋﻪﮔﻪﺭ ﮬﻪﻣﻤﯩﺴﻰ ﺷﻪﺭﺗﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﺳﻪ ﺭﺍﺳﺘﻨﻰ ،ﺋﯘﻧﺪﺍﻕ ﺑﻮﻟﻤﯩﺴﺎ ﻳﺎﻟﻐﺎﻧﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ. ﻣﻪﺳﯩﻠﻪﻥ :ﮬﻪﺭﺑﯩﺮ ﺯﺍﻛﺎﺯ ﻣﯩﻘﺪﺍﺭﯨﻨﯩﯔ ﻣﯘﺳﺒﻪﺕ ﺳـﺎﻥ ﺑﻮﻟـﯘﺵ ﺷـﻪﺭﺗﯩﻨﻰ ﻗﺎﻧﻪﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨـﺪﯨﻐﺎﻥ ﻳـﺎﻛﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﻣﻪﻳﺪﯨﻐﺎﻧﻠﯩﻘﯩﻨﻰ ﺗﻪﻛﺸﯜﺭﯛﭖ ﺑﺎﻗﯩﻠﻰ: ﻛﻮﺩ 4.45
bool result = (from c in customers from o in c.Orders select o) .All(o => o.Quantity > 0); result = Enumerable.Empty().All(o => o.Quantity > 0); //false ﺋﻪﺳــﻜﻪﺭﺗﯩﺶ :ﺋﻪﮔﻪﺭ Allﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﻗــﯘﺭﯗﻕ ﺗﯩﺰﻣﯩﻐــﺎ ﺋﯩﺸﻠﯩﺘﯩﻠــﺴﻪ ﻧﻪﺗﯩﺠـﺴﯩﻰ ﺑﯩــﺮﺩﻩﻙ ﺭﺍﺳــﺖ ﺑﻮﻟﯩﺪﯗ.
) Containsﺑﺎﺭﻣﯘ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( ﺑﯧــﺮﯨﻠﮕﻪﻥ ﺋﻪﺯﺍﻧﯩــﯔ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣﯩــﺪﺍ ﺑــﺎﺭ -ﻳــﻮﻗﻠﯩﻘﯩﻨﻰ ﺗﻪﻛــﺸﯜﺭﯨﺪﯗ .ﺑــﺎﺭ ﺑﻮﻟــﺴﺎ ﺭﺍﺳــﺘﻨﻰ ،ﺑﻮﻟﻤﯩــﺴﺎ ﻳﺎﻟﻐﺎﻧﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ .ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ:
71
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
public static bool Contains( this IEnumerable source, T value); public static bool Contains( this IEnumerable source, T value, ) IEqualityComparer comparer ﺋﻪﮔﻪﺭ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ > ICollection.ﻧـﻰ ﺋﯩﺸﻠﯩﺘﯩﺪﯗ. ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻣﯩﺴﺎﻟﺪﺍ ﺗـﯘﻧﺠﻰ ﺧﯧﺮﯨـﺪﺍﺭﻧﯩﯔ ﺯﺍﻛـﺎﺯﻟﯩﺮﻯ ﺋﯩﭽﯩـﺪﻩ ﺑﯧـﺮﯨﻠﮕﻪﻥ ﺯﺍﻛﺎﺯﻧﯩـﯔ ﺑـﺎﺭ -ﻳـﻮﻗﻠﯩﻘﻰ ﺗﻪﻛﺸﯜﺭﯛﻟﺪﻯ:
orderOfProductOne = new Order {Quantity = 3, IdProduct = 1 , Shipped = false, Month = "January"}; bool result = customers[0].Orders.Contains(orderOfProductOne);
Partitioningﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﭘﺎﺭﭼﯩﻼﺵ( ﺑﻪﺯﯨﺪﻩ ﺗﯩﺰﻣﯩﻨﯩﯔ ﻣﻪﻟﯘﻡ ﺑﯚﻟﯩﻜﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻏﺎ ﻧﯩﺴﺒﻪﺗﻪﻧﻼ ﻣﻪﺷﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﯧـﺮﯨﺶ ﺗـﻮﻏﺮﺍ ﻛﯧﻠﯩـﺪﯗ. ﻣﻪﺳـــﯩﻠﻪﻥ :ﺧﯧﺮﯨـــﺪﺍﺭﻻﺭ ﺗﯩﺰﻣﯩـــﺴﯩﺪﯨﻜﻰ ﺋﺎﻟـــﺪﯨﻨﻘﻰ Nﻧﻪﭘﻪﺭ ﺧﯧﺮﯨـــﺪﺍﺭﻧﯩﯔ ﺋﯘﭼﯘﺭﯨﻐـــﺎ ﺋﯧﺮﯨـــﺸﯩﺶ ﺩﯦﮕﻪﻧﺪﻩﻙ .ﺋﻪﻟﯟﻩﺗﺘﻪ ﺑﯘﻧﺪﺍﻕ ﻣﻪﺳﯩﻠﯩﻠﻪﺭﻧﻰ Whereﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺑﯩـﻠﻪﻥ Selectﻣﻪﺷﻐﯘﻻﺗﭽﯩـﺴﯩﻐﺎ ﻧﯚﻟﺪﯨﻦ ﺑﺎﺷﻠﯩﻨﯩﺪﯨﻐﺎﻥ ﺗﻪﺭﺗﯩﭗ ﻧﻮﻣـﯘﺭﯨﻨﻰ ﻛﯚﺭﺳـﻪﺗﻜﯜﭼﻨﯩﯔ ﭘـﺎﺭﺍﻣﯧﺘﯩﺮﻯ ﻗﯩﻠﯩـﭗ ﺑﯧـﺮﯨﺶ ﺋـﺎﺭﻗﯩﻠﯩﻘﻤﯘ ﮬﻪﻝ ﻗﯩﻼﻻﻳﻤﯩﺰ .ﻟﯧﻜﯩﻦ ﺋﯘﻧﯩﯔ ﺩﺍﺋﯩﻢ ﻗﻮﻻﻳﻠﯩﻖ ،ﺑﯩﯟﺍﺳﺘﻪ ﻳﻮﻝ ﺑﻮﻟﯘﺷﻰ ﻧﺎﺗـﺎﻳﯩﻦ .ﺷـﯘﯕﺎ Linqﺩﯨﻜـﻰ ﻣﯘﺷﯘﻧﺪﺍﻕ ﻣﻪﺳﯩﻠﯩﻠﻪﺭﮔﻪ ﺧﺎﺱ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭﻧﻰ ﺋﯩﺸﻠﯩﺘﯩﺶ ﻳﺎﺧﺸﻰ ﺗﺎﻟﻼﺵ. ﺑﯘ ﺗﯜﺭﺩﯨﻜﻰ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ ﺋﺎﺭﯨـﺴﺪﯨﻜﻰ Takeﺑﯩـﻠﻪﻥ TakeWhileﺑﻮﻟـﺴﺎ ﺋـﯚﺯ ﻳﻮﻟﻠﯩﺮﯨـﺪﺍ ﺋـﺎﻳﺮﯨﻢ- ﺋﺎﻳﺮﯨﻢ ﮬﺎﻟﺪﺍ ﺋﺎﻟﺪﯨﻨﻘﻰ Nﺩﺍﻧﻪ ﺋﻪﺯﺍ ﻳﺎﻛﻰ ﺑﯧﺮﯨﻠﮕﻪﻥ ﺷـﻪﺭﺗﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧـﺪﯛﺭﮔﯩﭽﻪ ﺋﺎﻟـﺪﯨﻨﻘﻰ ﻣـﺎﻧﭽﻪ ﺋﻪﺯﺍﻧﻰ ﺋﺎﻟﯩﺪﯗ. Skipﯞﻩ SkipWhileﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ Takeﺑﯩﻠﻪﻥ TakeWhileﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯔ ﺗﻮﻟﯘﻗﻠﯩﻤﯩﺴﻰ ﺑﻮﻟﯘﭖ ،ﺋﺎﻟﺪﯨﻨﻘﻰ Nﺋﻪﺯﺍﻧﻰ ﻳﺎﻛﻰ ﺑﯧﺮﯨﻠﮕﻪﻥ ﺷﻪﺭﺗﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨﺪﯨﻐﺎﻥ ﺋﺎﻟﺪﯨﻨﻘﻰ ﻣﺎﻧﭽﻪ ﺋﻪﺯﺍﻧﻰ ﺋﺎﺗﻼﭖ ﺋﯚﺗﯜﭖ ﻛﯧﺘﯩﺪﯗ.
72
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
) Takeﻧﻰ -ﺋﯧﻠﯩﺶ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺋﻪﻧﺪﯨﺰﯨﮕﻪ ﻗﺎﺭﺍﯓ:
public static IEnumerable Take( this IEnumerable source, ;) int count ﺩﯦﻤﻪﻙ Takeﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩـﺪﯨﻜﻰ ﺋﺎﻟـﺪﯨﻨﻘﻰ countﺩﺍﻧﻪ ﺋﻪﺯﺍﻧـﻰ ﻗـﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﯨـﺪﯗ. ﺋﻪﮔﻪﺭ ﻛﯚﺯﻟﯩﻤﻪ ﻣﯩﻘﺪﺍﺭ ﻧﯚﻝ ﺑﻮﻟﺴﺎ ﻗﯘﺭﯗﻕ ﺗﯩﺰﻣﯩﻨﻰ ،ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣـﺎ ﺋﯘﺯﯗﻧﻠﯘﻗﯩـﺪﯨﻦ ﭼـﻮﯓ ﺑﻮﻟـﺴﺎ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩﻨﯩﯔ ﺋﯚﺯﯨﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ .ﺑﯘ ﻣﻪﺷﻐﯘﻻﺗﭽﻰ »ﺧﯧﺮﯨﺪﺍﻻﺭ ﺋﺎﺭﯨﺴﯩﺪﯨﻦ ﺯﺍﻛﺎﺯ ﭘﯘﻝ ﻣﯩﻘﺪﺍﺭﻯ ﺋﻪﯓ ﭼـﻮﯓ ﺑﻮﻟﻐﺎﻥ ﺋﺎﻟﺪﯨﻨﻘﻰ 2ﺧﯧﺮﯨﺪﺍﺭﻧﻰ ﺗﺎﻟﻼﺵ« ﺩﯦﮕﻪﻧﺪﻩﻙ ﻣﻪﺳﯩﻠﯩﻠﻪﺭﮔﻪ ﺗﻮﻟﯩﻤﯘ ﻣﺎﺱ ﻛﯧﻠﯩﺪﯗ .ﻣﻪﺳﯩﻠﻪﻥ: ﻛﻮﺩ 4.47
var topTwoCustomers = (from c in customers join o in ( from c in customers from o in c.Orders join p in products on o.IdProduct equals p.IdProduct select new { c.Name, OrderAmount = o.Quantity * p.Price } ) on c.Name equals o.Name into customersWithOrders let TotalAmount = customersWithOrders.Sum(o => o.OrderAmount) orderby TotalAmount descending select new { c.Name, TotalAmount } ).Take(2); ﻛﯚﺭﮔﻪﻧﺴﯩﺰ! ﮔﻪﺭﭼﻪ ﺋﻮﻣﯘﻣﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺋﯩﻨﺘﺎﻳﯩﻦ ﭼﯩﺮﻣﺎﺵ ﺑﻮﻟﻐﺎﻥ ﺑﯩﻠﻪﻥ Take ،ﻧﻰ ﺋﻮﺭﯗﻧﻼﺷﺘﯘﺭﯗﺵ ﻧﺎﮬﺎﻳﯩﺘﻰ ﺋﺎﺩﺩﯨﻲ .ﻳﯘﻗﯩﺮﯨﻘﻰ ﺋﯩﭙﺎﺩﯨﺪﻩ ﺑﯘﺭﯗﻥ ﺳﯚﺯﻟﯩﮕﻪﻥ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺧﺎﺱ ﺳﯚﺯﻟﯩﺮﯨﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﺶ ﺑﯩﻠﻪﻥ ﺑﯩﺮ ﯞﺍﻗﯩﺘﺘﺎ ﻳﯧﯖﻰ ﺧﺎﺱ ﺳﯚﺯ letﻣﯘ ﺋﯩﺸﻠﯩﺘﯩﻠﺪﻯ let .ﺧﺎﺱ ﺳﯚﺯﻯ ﺋﯩﭙﺎﺩﻩ ﺋﯩﭽﯩﺪﻩ ﻣﻪﻟﯘﻡ ﮬﻪﺭﭖ-ﺑﻪﻟﮕﻪ ﺗﯩﻤﯩﺴﯩﻨﻰ ﻣﻪﻟﯘﻡ ﻗﯩﻤﻤﻪﺗﻜﻪ ﻳﺎﻛﻰ ﻣﻪﻟﯘﻡ ﻓﻮﺭﻣﯩﻼ ﻗﯩﻤﻤﯩﺘﯩﮕﻪ ﺗﻪﯕﺪﺍﺵ ﻗﯩﻠﯩﺶ ﺭﻭﻟﯩﻨﻰ ﺋﻮﻳﻨﺎﻳﺪﯗ .ﺯﺍﻏﺮﺍ ﺗﯩﻞ ﺑﻮﻳﯩﭽﻪ ﺋﯩﭙﺎﺩﻩ ﺋﯩﭽﯩﺪﻩ ﻳﻪﺭﻟﯩﻚ ﺋﯚﺯﮔﻪﺭﮔﯜﭼﻰ ﻣﯩﻘﺪﺍﺭ ﺋﯧﻨﯩﻘﻼﻳﺪﯗ ﺩﯦﺴﻪﻛﻤﯘ ﺑﻮﻟﯩﺪﯗ)ﺑﯘ ﺯﺍﻏﺮﺍ ﺗﯩﻞ ﺋﻪﻣﻪﺳﻤﯘ ﻳﺎ...
( .ﻣﻪﺳﯩﻠﻪﻥ :ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﯩﺴﺎﻟﯩﻤﯩﺰﺩﺍ ﺯﺍﻛﺎﺯﻯ ﺑﺎﺭ ﺧﯧﺮﯨﺪﺍﺭﻧﯩﯔ
ﺑﺎﺭﻟﯩﻖ ﺯﺍﻛﺎﺯﻟﯩﺮﯨﻨﯩﯔ ﻗﯩﻤﻤﻪﺕ ﻳﯩﻐﯩﻨﺪﯨﺴﯩﻨﻰ TotalAmoutﺩﯦﮕﻪﻧﮕﻪ ﺳﺎﻗﻼﭖ ﺗﯘﺭﺩﯗﻕ.
73
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
) TakeWhileﭼﺎﻏﺪﺍ -ﺋﯧﻠﯩﺶ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( ﺋﯩﺸﻠﯩﺘﯩﺶ ﺋﯘﺳﯘﻟﻰ Takeﺑﯩـﻠﻪﻥ ﺋﻮﺧﺸﯩـﺸﯩﭗ ﻛﯧﺘﯩـﺪﯨﻐﺎﻥ ﺑﻮﻟـﯘﭖ ،ﺑﯘﻧﯩﯖـﺪﺍ ﺋﺎﻟـﺪﯨﻨﻘﻰ ﻣﺎﻧﭽﯩـﺴﯩﻨﻰ ﺋﻪﻣﻪﺱ ،ﺑﻪﻟﻜﻰ ﺋﺎﻟﺪﯨﻨﻘﻰ ﺋﻪﺯﺍﻻﺭﻧﻰ ﺗـﺎﻛﻰ ﺷـﻪﺭﺕ ﻗﺎﻧـﺎﺋﻪﺗﻠﻪﻧﻤﯩﮕﯩﭽﻪ ﺋﺎﻟﯩـﺪﯗ .ﺗﯚﯞﻩﻧـﺪﯨﻜﯩﻠﻪﺭ ﺋﯘﻧﯩـﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ:
public static IEnumerable TakeWhile( this IEnumerable source, Func predicate); public static IEnumerable TakeWhile( this IEnumerable source, ;) Func predicate ﺑﯩﺮﯨﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ،ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﻨﯩﯔ ﻧﯚﻟﯩﻨﭽﻰ ﺋﻪﺯﺍﺳﯩﺪﯨﻦ ﺑﺎﺷﻼﭖ ﭼﺎﺭﻻﺵ ﺋﯧﻠﯩـﭗ ﺋﯘﻧﯩـﯔ ﻛﯚﺭﺳـــــﻪﺗﻜﯜﭼﺘﯩﻜﻰ ﺷـــــﻪﺭﺗﻜﻪ ﭼﯜﺷـــــﯩﺪﯨﻐﺎﻧﻴﺎﻛﻰ ﭼﯜﺷـــــﻤﻪﻳﺪﯨﻐﻨﺎﻟﯩﻘﯩﻨﻰ ﺗﻪﻛـــــﺸﯜﺭﯨﺪﯗ ،ﺋﻪﮔﻪﺭ ﭼﯜﺷﺴﻪ)ﻛﯚﺭﺳﻪﺗﻤﻪ ﻗﯩﻤﻤﯩﺘﻰ ﺭﺍﺳﺖ ﺑﻮﻟـﺴﺎ( ﺋـﯘﻧﻰ ﺋـﯘ ﻧﻪﺗﯩـﺠﻪ ﺗﻮﭘﻠﯩﻤﯩﻐـﺎ ﻗﻮﺷـﯘﭖ ﺑﻮﻟـﯘﭖ ﻛﯧﻴﯩﻨﻜـﻰ ﺋﻪﺯﺍﻧﻰ ﺋﻮﺧﺸﺎﺵ ﺋﯘﺳﯘﻟﺪﺍ ﺗﻪﻛﺸﯜﺭﯨﺪﯗ .ﺑﯘ ﺟﻪﺭﻳـﺎﻥ ﺗـﺎﻛﻰ ﻣﻪﻟـﯘﻡ ﺋﻪﺯﺍ ﺷـﻪﺭﺗﻜﻪ ﭼﯜﺷـﻤﯩﮕﻪﻧﮕﻪ ﻳـﺎﻛﻰ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﻘﻰ ﺋﻪﺯﺍﻧﻰ ﺗﻪﻛﺸﯜﺭﯛﺵ ﺗﺎﻣﺎﻣﻼﻧﻐﺎﻧﻐﺎ ﻗﻪﺩﻩﺭ ﺩﺍﯞﺍﻣﻠﯩﺸﯩﺪﯗ. ﺋﯩﻜﻜﯩﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﭘﺎﺭﺍﻣﯧﺘﯩﺮ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﯩـﺮﺩﺍﻧﻪ ﭘﯜﺗـﯜﻥ ﺳـﺎﻥ ﻳـﻮﻟﻼﭖ ﺑﯧﺮﯨﻤﯩـﺰ ،ﭼـﺎﺭﻻﺵ ﻣﻪﺷﻐﯘﻻﺗﻰ ﺋﯘﺷﺒﯘ ﺳﺎﻥ ﺗﻪﺭﺗﯩﭙﻠﯩﻚ ﺋﻪﺯﺍﺩﯨﻦ ﺑﺎﺷﻠﯩﻨﯩﺪﯗ. ﺋﯘﻧﯩﯖﺪﯨﻦ ﺑﺎﺷﻘﺎ ﺷﻪﺭﺕ ﻛﯚﺭﺳﻪﺗﻤﯩﺴﯩﻨﻰ ﻣﯘﯞﺍﭘﯩﻖ ﺗﯜﺯﯛﺵ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺗﯧﺨﯩﻤﯘ ﻣـﯘﺭﻩﻛﻜﻪﭖ ﻣﻪﺳـﯩﻠﯩﻠﻪﺭﻧﻰ ﮬﻪﻝ ﻗﯩﻼﻻﻳﻤﯩﺰ .ﻣﻪﺳﯩﻠﻪﻥ :ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻣﯩﺴﺎﻟﺪﺍ ﺯﺍﻛﺎﺯ ﻣﯩﻘـﺪﺍﺭﻯ ﻗﯩﻤﻤﯩﺘـﻰ ﺋﻮﻣـﯘﻣﻰ ﻗﯩﻤﻤﻪﺗﻨﯩـﯔ %80 ﺗﯩﻨﻰ ﺋﯩﮕﯩﻠﻪﻳﺪﯨﻐﺎﻥ ﺋﺎﻟﺪﯨﻨﻘﻰ ﺧﯧﯩﺮﺩﺍﺭﻻﺭﻏﺎ ﺋﯧﺮﯨﺸﯩﺪﯗ: ﻛﻮﺩ 4.48
// var limitAmount = globalAmount * 0.8m; var aggregated = 0m; var topCustomers = (from c in customers join o in ( from c in customers from o in c.Orders join p in products on o.IdProduct equals p.IdProduct select new { c.Name, OrderAmount = o.Quantity * p.Price } ) on c.Name equals o.Name into customersWithOrders
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
let TotalAmount = customersWithOrders.Sum(o => o.OrderAmount) orderby TotalAmount descending select new { c.Name, TotalAmount } ) .TakeWhile( X => { bool result = aggregated < limitAmount; aggregated += X.TotalAmount; return result; } );
SkipWhile ﺑﯩﻠﻪﻥSkip ﻟﻪﺭﻧﯩﯖﻜﯩــﮕﻪ ﺋﯩﻨﺘــﺎﻳﯩﻦTakeWhile ﺑﯩــﻠﻪﻥTake ﻧﯩــﯔ ﺋﻪﻧــﺪﯨﺰﯨﻠﯩﺮﻯSkipWhile ﺑﯩــﻠﻪﻥSkip : ﻳﻪﻧﻰ.ﺋﻮﺧﺸﯩﺸﯩﭗ ﻛﯧﺘﯩﺪﯗ
public static IEnumerable Skip( this IEnumerable source, int count); public static IEnumerable SkipWhile( this IEnumerable source, Func predicate); public static IEnumerable SkipWhile( this IEnumerable source, Func predicate); . ﻧﯩﯔ ﺗﻮﻟﯘﻗﻠﯩﻐـﯘﭼﯩﻠﺮﻯ ﺩﻩﭖ ﺋﯧﻴﺘﻘﺎﻧﯩـﺪﯗﻕTakeWhile ﺑﯩﻠﻪﻥTake ﻳﺎﻳﺎﻡ ﺗﯧﺨﻰ ﺑﯘ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ : ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻛﻮﺩ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ﺗﻮﻟﯘﻕ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ،ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ
var result = customers.Take(3).Union(customers.Skip(3)); var result = customers.TakeWhile(p).Union(customers.SkipWhile(p));
74
75
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﯧﻠﯧﻤﯧﻨﺖ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﯧﻠﯧﻤﯧﻨــﺖ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺗﯩﺰﻣــﺎ ﺋﯩﭽﯩــﺪﯨﻜﻰ ﻣﻪﻟــﯘﻡ ﺑﯩــﺮﻻ ﺋﻪﺯﺍﻏــﺎ ﺋﺎﻻﻗﯩﻠــﺪﺍﺭ ﻣﻪﺷــﻐﯘﻻﺗﻨﻰ ﺋﯧﻠﯩــﭗ ﺑﺎﺭﯨــﺪﯨﻐﺎﻥ ﺑﻮﻟــﯘﭖ ،ﻣﻪﻟــﯘﻡ ﺋﻮﺭﯗﻧــﺪﯨﻜﻰ ﻳــﺎﻛﻰ ﺷــﻪﺭﺗﻜﻪ ﺋﯘﻳﻐــﯘﻥ ﺑﯩــﺮﻻ ﺋﻪﺯﺍﻧــﻰ ﻗﺎﻳﺘﯘﺭﯨــﺪﯗ .ﺋﻪﮔﻪﺭ ﺗﺎﭘﺎﻟﻤﯩﺴﺎ ﻛﯚﯕﯜﻟﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺕ ﺋﻪﺯﺍﺳﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ.
) Firstﺗﯘﻧﺠﻰ ﻣﻪﺷﻐﯘﻻﺗﯩﭽﯩﺴﻰ( Firstﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﺗــﯘﻧﺠﻰ ﻳــﺎﻛﻰ )ﺋﻪﮔﻪﺭ ﻛﯚﺭﺳــﻪﺗﻤﻪ ﺷــﻪﺭﺗﻰ ﺑﯧﺮﯨﻠــﺴﻪ( ﺷــﻪﺭﺗﻨﻰ ﻗﺎﻧﻪﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨﺪﯨﻐﺎﻥ ﯞﻩ ﻳﺎﻛﻰ ﺋﻮﺭﯗﻥ ﻗﺎﺋﯩﺪﯨﺴﯩﮕﻪ ﭼﯜﺷﯩﺪﯨﻐﺎﻥ ﺗﯘﻧﺠﻰ ﺋﻪﺯﺍﻧﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ:
public static T First( this IEnumerable source); public static T First( this IEnumerable source, Func predicate); ﺑﯩﺮﯨﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﻨﯩﯔ ﺑﯩﺮﯨﻨﭽﻰ ﺋﯧﻠﯧﻤﯧﻨﺘﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨـﺪﯗ .ﺋﯩﻜﻜﯩﻨﭽـﻰ ﺧﯩﻠﯩـﺪﺍ ﺑﯧــﺮﯨﻠﮕﻪﻥ ﺷــﻪﺭﺗﻜﻪ ﭼﯜﺷــﯩﺪﯨﻐﺎﻥ ﺗــﯘﻧﺠﻰ ﺋﯧﻠﯧﻤﯧﻨﺘﻨــﻰ ﻗﺎﻳﺘﯘﺭﯨــﺪﯗ .ﺋﻪﮔﻪﺭ ﺷــﻪﺭﺗﻜﻪ ﭼﯜﺷــﯩﺪﯨﻐﺎﻥ ﺋﯧﻠﯧﻤﯧﻨﺖ ﺗﯧﭙﯩﻠﻤﯩﺴﺎ ﻳﺎﻛﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﺎ ﻗـﯘﺭﯗﻕ ﺑﻮﻟـﺴﺎ ،ﻣﻪﺷـﻐﯘﻻﺗﭽﻰ InvalidOperationException ﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﻗﻮﻳﯘﭖ ﺑﯧﺮﯨﺪﯗ .ﺗﯚﯞﻩﻧﺪﻩ ﺑﯩﺮﻣﯩﺴﺎﻝ: ﻛﻮﺩ 4.49
ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ USAﺑﻮﻟﻐﺎﻥ ﺗﯘﻧﺠﻰ ﺧﯧﺮﯨﺪﺍﺭﻏﺎ ﺋﯧﺮﯨﺸﯩﺶ
var item = customers.First(c => c.Country == Countries.USA); ﺋﻪﻟﯟﻩﺗﺘﻪ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﻪﻗﺴﻪﺗﻨﻰ ﺗﯚﯞﻩﻧﻜﻰ ﺋﯘﺳﯘﻝ ﺋﺎﺭﻗﯩﻠﯩﻘﻤﯘ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﺍﻻﻳﻤﯩﺰ:
;)var item = customers.Where(c => c.Country == Countries.USA).Take(1 ﺑﯩﺮﺍﻕ Firstﺋﯩﭙﺎﺩﻩ ﻣﻪﻗﺴﯩﺘﯩﻨﻰ ﺗﯧﺨﯩﻤﯘ ﺋﯧﻨﯩﻖ ﺋﯩﭙﺎﺩﯨﻠﻴﻪﻟﻪﻳﺪﯗ.
FirstOrDefault FirstOrDefaultﻧﻰ »ﺗﯘﻧﺠﯩﺴﻰ ﺑﻮﻟﻤﯩﺴﺎ ﻛﯚﯕﯜﻟﺪﯨﻜﯩﻨﻰ« ﺩﻩﭖ ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﺴﺎﻡ ﻣﯘﯞﺍﭘﯩﻖ ﺩﻩﭖ ﺋﻮﻳﻠﯩﺪﯨﻢ .ﺋﯘﻧﯩﯔ ﻣﻪﺷﻐﯘﻻﺕ ﭘﯩﺮﯨﻨﺴﯩﭙﻰ ` Firstﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ ﺑﻮﻟﯘﭖ ،ﺑﯩﺮﺩﯨﻦ -ﺑﯩﺮ ﭘﻪﺭﻗﻰ .ﺋﻪﮔﻪﺭ ﺷﻪﺭﺗﻜﻪ ﺋﯘﻳﻐﯘﻥ ﮬﯧﭽﻘﺎﻧﺪﺍﻕ ﺋﯧﻠﻤﯧﻨﺖ ﺗﯧﭙﯩﻠﻤﯩﺴﺎ ﻣﻪﻧﺒﻪ ﺋﻪﺯﺍﻟﯧﺮﯨﻨﻰ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭙﻠﯩﻖ nullﻧﻰ، ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﺴﺎ ﺷﯘ ﺗﯩﭙﻨﯩﯔ nullableﺋﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ .ﺗﯚﯞﻩﻧﺪﻩ ﺑﯩﺮ ﻣﯩﺴﺎﻝ:
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
4.50 ﻛﻮﺩ
var item = customers.FirstOrDefault(c => c.City == "Las Vegas"); Console.WriteLine(item == null ? "null" : item.ToString()); // null IEnumerable emptyCustomers = Enumerable.Empty(); item = emptyCustomers.FirstOrDefault(c => c.City == "Las Vegas"); Console.WriteLine(item == null ? "null" : item.ToString()); // null
LastOrDefault ﺑﯩﻠﻪﻥLast ﻻﺭﻏﺎ ﺋﻮﺧﺸﯩﺸﯩﭗ ﻛﯧﺘﯩﺪﯨﻐﺎﻥFirstOrDefault ﺑﯩﻠﻪﻥFirst ﻻﺭ ﺑﻮﻟﺴﺎLastOrDefault ﺑﯩﻠﻪﻥLast ﺑﺎﺷـﻘﺎ. ﺑﯘﻻﺭ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨـﺪﯨﻜﯩﻨﻰ ﺋﺎﻟﯩـﺪﯗ، ﺗﯘﻧﺠﯩﺴﯩﻨﻰ ﺋﺎﻟﺴﺎFirstOrDefault ﺑﯩﻠﻪﻥFirst ،ﺑﻮﻟﯘﭖ : ﺗﯚﯞﻩﻧﺪﯨﻜﯩﻠﯩﺮﻯ ﺋﯘﻻﺭﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ. ﺋﻮﺧﺸﺎﺵ-ﺑﺎﺭﻟﯩﻖ ﻗﯘﺭﯗﻟﻤﯩﻠﯩﺮﻯ ﺋﻮﭘﻤﯘ
public static T Last( this IEnumerable source); public static T Last( this IEnumerable source, Func predicate); public static T LastOrDefault( this IEnumerable source); public static T LastOrDefault( this IEnumerable source, Func predicate);
Single ﺗﯩﺰﻣﯩﻼﺭﻧﯩـﯔ ﯞﻩﻛﯩﻠـﻰ ﺳـﯜﭘﯩﺘﯩﺪﻩ( ﺋﺎﻟﻤـﺎﻗﭽﻰ:ﺋﻪﮔﻪﺭ ﺗﯩﺰﻣﯩﺪﯨﻦ ﺑﯩﺮﺗﺎﻝ ﺋﻪﺯﺍﻧﻰ ﺷـﯘﻧﺪﺍﻗﻼ )ﻣﻪﺳـﯩﻠﻪﻥ : ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ. ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﯔSingle ﺑﻮﻟﺴﯩﯖﯩﺰ
public static T Single( this IEnumerable source); public static T Single( this IEnumerable source, Func predicate);
76
77
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺋﻪﮔﻪﺭ ﻛﯚﺭﺳﻪﺗﻜﯜﭺ ﺷﻪﺭﺗﻰ ﺑﯧﺮﯨﻠﻤﯩﺴﻪ ،ﻗﺎﻳﺘﯩﺪﯨﻐﯩﻨﻰ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺑﯩﺮﯨﻨﭽﻰ ﺋﯧﻠﯧﻤﯧﻨﺖ ﺑﻮﻟﯩﺪﯗ .ﺋﯘﻧﺪﺍﻕ ﺑﻮﻟﻤﯩﻐﺎﻧﺪﺍ ﺷﻪﺭﺗﻜﻪ ﭼﯜﺷﯩﺪﯨﻐﺎﻥ ﺑﯩﺮﺗﺎﻝ ﺋﯧﻠﯧﻤﯧﻨﺖ ﺑﻮﻟﯩﺪﯗ .ﺋﻪﮔﻪﺭ ﻛﯚﺭﺳﻪﺗﻜﯜﭺ ﺑﻮﻟﻤﯩﺴﺎ ﮬﻪﻣﺪﻩ ﺗﯩﺰﻣﯩﺪﺍ ﺑﯩﺮﺩﯨﻦ ﺋﺎﺭﺗﯘﻕ ﺋﯧﻠﯧﻤﻨﺖ ﺑﻮﻟﺴﺎ InvalidOperationExceptionﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﻗﻮﻳﯘﭖ ﺑﯧﺮﯨﻠﯩﺪﯗ. ﺋﻪﮔﻪﺭ ﻛﯚﺭﺳﻪﺗﻜﯜﭺ ﺑﯧﺮﯨﻠﺴﻪ ﻟﯧﻜﯩﻦ ﺗﯩﺰﻣﯩﺪﺍ ﺷﻪﺭﺗﻜﻪ ﭼﯜﺷﯩﺪﯨﻐﺎﻥ ﺑﯩﺮﻣﯘ ﺋﯧﻠﯧﻤﯧﻨﺖ ﺑﻮﻟﻤﯩﺴﺎ ﻳﺎﻛﻰ ﺗﯩﺰﻣﺎ ﻗﯘﺭﯗﻕ ﺑﻮﻟﺴﺎ InvalidOperationExceptionﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨﺪﯗ .ﺗﯚﯞﻩﻧﺪﯨﻜﯩﻠﻪﺭ ﺋﻮﺧﺸﯩﻤﯩﻐﺎﻥ ﺋﻪﮬﯟﺍﻟﻼﺭﻏﺎ ﻣﺎﺱ ﻣﯩﺴﺎﻟﻼﺭ: ﻛﻮﺩ 4.51
Product 1ﻧﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ //
var item = products.Single(p => p.IdProduct == 1); Console.WriteLine(item == null ? "null" : item.ToString()); InvalidOperationExceptionﭘﯧﺸﻜﯩﻠﻰ ﭼﯩﻘﯩﺮﯨﺪﯗ// item = products.Single(); Console.WriteLine(item == null ? "null" : item.ToString()); InvalidOperationExceptionﭘﯧﺸﻜﯩﻠﻰ ﭼﯩﻘﯩﺮﯨﺪﯗ// IEnumerable emptyProducts = Enumerable.Empty(); item = emptyProducts.Single(p => p.IdProduct == 1); Console.WriteLine(item == null ? "null" : item.ToString());
SingleOrDefault SingleOrDefaultﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﻗﯘﺭﯗﻕ ﻳـﺎﻛﻰ ﺷـﻪﺭﺗﻜﻪ ﺋﯘﻳﻐـﯘﻥ ﺋﯧﻠﯧﻤﯧﻨـﺖ ﺑﻮﻟﻤﯩﻐـﺎﻥ ﺗﯩﺰﻣﯩـﺪﯨﻦ ﻛﯚﯕﯜﻟـــﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗﻨـــﻰ ﻗﺎﻳﺘﯘﺭﯨـــﺪﯗ .ﺑـــﯘ ﻳﻪﺭﺩﯨﻜـــﻰ »ﻛﯚﯕﯜﻟـــﺪﯨﻜﻰ ﻗﯩﻤـــﻤﻪﺕ« FirstOrDefault ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﺪﺍ ﺳﯚﺯﻟﻪﻧﮕﯩﻨﻰ ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ. ﺋﻪﺳﻜﻪﺭﺗﯩﺶ default :ﻗﯩﻤﻤﻪﺕ ﭘﻪﻗﻪﺕ ﺷﻪﺭﺗﻜﻪ ﺋﯘﻳﻐـﯘﻥ ﺋﯧﻠﯧﻤﯧﻨـﺖ ﺗﯧﭙﯩﻠﻤﯩﻐﺎﻧـﺪﯨﻼ ﻗﺎﻳﺘﯩـﺪﯗ .ﺋﻪﮔﻪﺭ ﺗﯩﺰﻣﯩـــﺪﺍ ﺷـــﻪﺭﺗﻜﻪ ﺋﯘﻳﻐـــﯘﻥ ﺑﯩـــﺮﺩﯨﻦ ﺋــــﺎﺭﺗﯘﻕ ﺋﯧﻠﻤﯧﻨﯧﻨـــﺖ ﺑﻮﻟـــﯘﭖ ﻗﺎﻟـــﺴﺎﻕ ﻣﻪﺷــــﻐﯘﻻﺗﯩﭽﻰ InvalidOperationExceptionﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨﺪﯗ.
ElementAtﺑﯩﻠﻪﻥ ElementAtOrDefault ElementsAtﺑﯩـــﻠﻪﻥ ElementAtOrDefaultﺗﯩﺰﻣﯩﻨﯩـــﯔ ﺑﻪﻟﮕﯩﻠﻪﻧـــﮕﻪﻥ ﺋﻮﺭﯗﻧـــﺪﯨﻜﻰ ﺋﯧﻠﯧﻤﯧﻨﺘﻨـــﻰ ﺋﯧﻠﯩﺶ ﺋﯜﭼﯜﻥ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ:
ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕLINQ
www.udmish.cn
public static T ElementAt( this IEnumerable source, int index); public static T ElementAtOrDefault( this IEnumerable source, int index); ﭘﺎﺭﺍﻣﯧﺘﯩﺮ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻗﺎﻳﺴﻰ ﺋﻮﺭﯗﻧﺪﯨﻜﻰ ﺋﯧﻠﯧﻤﯧﻨﺘﻨـﻰ ﺋﯧﻠﯩـﺸﻨﻰ ﻛﯚﺭﺳـﯩﺘﯩﭗ ﺑﯧﻜﯩﺘﯩـﭗ، ﺗﻪElementAt ﺋﯩﻜﻜﯩﻨـﻰ ﻳﻮﻟﻠﯩـﺴﯩﯖﯩﺰ ﺋـﯜﭼﯩﻨﭽﻰ، ﺩﯦـﻤﻪﻙ. ﺗﻪﺭﺗﯩـﭗ ﻧﻮﻣـﯘﺭﻯ ﻧﯚﻟـﺪﯨﻦ ﺑﺎﺷـﻠﯩﻨﯩﺪﯗ.ﺑﯧـﺮﯨﺶ ﻛﯧـﺮﻩﻙ ﺋﻪﮔﻪﺭ ﺑﻪﺭﮔﻪﻥ ﺳﺎﻧﯩﯖﯩﺰ ﻣﻪﻧﻔﻰ ﺑﻮﻟﺴﺎ ﻳﺎﻛﺎ ﺗﯩﺰﻣﺎ ﺳﺎﻥ ﭼﻪﻛﻠﯩﻤﯩﺴﯩﻦ ﺋﯧـﺸﯩﭗ.ﺋﯧﻠﯧﻤﯧﻨﺘﯩﻐﺎ ﺋﯧﺮﯨﺸﯩﺴﯩﺰ . ﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨﺪﯗArgumentOutOfRangeException ﻣﻪﺷﻐﯘﻻﺕ،ﻛﻪﺗﺴﻪ ، ﺗﯩﻜﻰ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﻗﻮﻳﯘﭖ ﺑﯧﺮﯨـﺪﯨﻐﺎﻥ ﺋﻪﮬـﯟﺍﻟﻼﺭﺩﺍElementAt ، ﺗﺎ ﺑﻮﻟﺴﺎElementAtOrDefault ﻗــﺎﻳﺘﯘﺭﯗﺵ ﭘﯩﺮﯨﻨــﺴﯩﭙﻰ.ﺑﯩﻨﻮﺭﻣــﺎﻟﻠﯩﻖ ﻗﻮﻳــﯘﭖ ﺑﯧﺮﯨــﺸﻨﯩﯔ ﺋﻮﺭﻧﯩﻐــﺎ ﻛﯚﯕﯜﻟــﺪﯨﻜﻰ ﻗﯩﻤــﻤﻪﺕ ﻗﺎﻳﺘﯘﺭﯨــﺪﯗ ﺗﯚﯞﻩﻧــﺪﻩ ﺋﯘﻻﺭﻧﯩــﯔ ﺋﯩﺸﻠﯩﺘﯩﻠﯩــﺸﯩﮕﻪ ﺋﺎﺋﯩــﺖ ﻣﯩــﺴﺎﻝ. ﻧﯩﯖﻜــﻰ ﺑﯩــﻠﻪﻥ ﺋﻮﺧــﺸﺎﺵFirstOrDefault :ﺑﯧﺮﯨﻠﺪﻯ 4.52 ﻛﻮﺩ
// ﻧﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗProduct 2
var item = products.ElementAt(2); Console.WriteLine(item == null ? "null" : item.ToString()); // ﻗﺎﻳﺘﯘﺭﯨﺪﯗ null
item = Enumerable.Empty().ElementAtOrDefault(6); Console.WriteLine(item == null ? "null" : item.ToString()); // ﻗﺎﻳﺘﯘﺭﯨﺪﯗ null
item = products.ElementAtOrDefault(6); Console.WriteLine(item == null ? "null" : item.ToString());
DefaultIfEmpty : ﻗﯘﺭﯗﻕ ﺗﯩﺰﻣﺎ ﺋﯜﭼﯜﻥ ﻛﯚﯕﻠﯩﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗDefaultIfEmpty
public static IEnumerable DefaultIfEmpty( this IEnumerable source); public static IEnumerable DefaultIfEmpty( this IEnumerable source, T defaultValue);
78
79
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺑﻪﻟﮕﯩﻠﯩﻤﯩﺴﻰ ﺑﻮﻳﯩﭽﻪ ،ﺋﯘ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ ﺗـﻮﭘﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨـﺪﯗ .ﺋﻪﮔﻪﺭ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣـﺎ ﻗـﯘﺭﯗﻕ ﺑﻮﻟﺴﺎ ،ﺑﯩﺮﯨﻨﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺪﻩ ) default(Tﻧﻰ ،ﺋﯩﻜﻜﯩﻨﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﭘﺎﺭﺍﻣﯧﺘﯩﺮ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﯧﺮﯨﻠﮕﻪﻥ defaultValueﻧﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ. ﺧﺎﺳﻼﺷﺘﯘﺭﯗﻟﻐﺎﻥ ﻛﯚﯕﯜﻟﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺕ ﻗﯘﺭﯗﯞﯦﻠﯩﺸﻨﯩﯔ ﭘﺎﻳﺪﯨﺴﻰ ﻛﯚﭖ .ﻣﻪﺳﯩﻠﻪﻥ ،ﮬﯧﭽﻘﺎﻧﺪﺍﻕ ﺋﯘﭼﯘﺭﻯ ﺑﻮﻟﻤﯩﻐﺎﻥ ﻗﯘﺭﯗﻕ ﺧﯧﺮﯨﺪﺍﺭ ﻻﺯﯨﻢ ﺑﻮﻟﻐﺎﻧﺪﺍ Emptyﻧﺎﻣﻠﯩﻖ ﺧﺎﺳﻠﯩﻖ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﯧﺮﯨﺸﻜﯩﻠﻰ ﺑﻮﻟﯩﺪﯨﻐﺎﻥ ﻗﯩﻠﺴﺎﻕ ﻣﯘﻧﺪﺍﻕ ﻳﺎﺯﯨﻤﯩﺰ:
public static Customer Empty { get { Customer empty = new Customer(); empty.Name = String.Empty; empty.Country = Countries.Italy; empty.City = String.Empty; empty.Orders = (new List(Enumerable.Empty())).ToArray(); return(empty); } } ﺑﻪﺯﯨﺪﻩ ﺑﯘﻧـﺪﺍﻕ ﻗﯩﻠﯩـﺶ ﻳﺎﺧـﺸﻰ ﺋﯩـﺶ ،ﺑﻮﻟﯘﭘﻤـﯘ ﺑـﯚﻟﻪﻙ ﺳـﯩﻨﯩﻘﻰ ﺋﯧﻠﯩـﭗ ﺑﺎﺭﻏﺎﻧـﺪﺍ ﺋﯩﻨﺘـﺎﻳﯩﻦ ﺋﻪﺱ ﻗﺎﺗﯩﺪﯗ .ﺋﯘﻧﯩﯖﺪﯨﻦ ﺑﺎﺷﻘﺎ ،ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ GroupJoinﻧـﻰ ﺋﯩـﺸﻠﯩﺘﯩﭗ ﺳـﻮﻝ -ﺳـﯩﺮﺗﻘﻰ ﮬﻪﻣـﺪﻩﻣﯩﻨﻰ ﺑﺎﻳﻘﯩﻐﺎﻧﺪﺍ Null ،ﺑﻮﻟﯘﺵ ﺋﯧﮫﺘﯩﻤﺎﻟﻠﯩﻘﻰ ﺑﻮﻟﻐﺎﻥ ﻧﻪﺗﯩﺠﯩﻨﻰ ﻛﯚﯕﯜﻟـﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗـﻜﻪ ﺋﺎﻳﻼﻧـﺪﯗﺭﯗﯞﯦﺘﯩﺶ ﻳﺎﺧﺸﻰ ﺋﺎﺩﻩﺕ. ﺗﯚﯞﻩﻧﺪﻩ DefaultEmptyﻧﻰ ﺋﯩﺸﻠﯩﺘﯩﺸﺘﯩﻦ ﺑﯩﺮ ﻣﯩﺴﺎﻝ: ﻛﻮﺩ 4.53
var expr = customers.DefaultIfEmpty(); var customers = Enumerable.Empty(); // Empty array IEnumerable customersEmpty = customers.DefaultIfEmpty(Customer.Empty);
80
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
ﺑﺎﺷﻘﺎ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ Concatﺑﯩﻠﻪﻥ SequanceEqualﻣﻪﺯﻛﯘﺭ ﭘﺎﺭﺍﮔﺮﺍﻓﺘﯩﻜﻰ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﻘﻰ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ.
) Concatﺋﯘﻻﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( Concatﺑﯩــﺮ ﺗﯩﺰﻣﯩﻨــﻰ ﻳﻪﻧﻪ ﺑﯩــﺮ ﺗﯩﺰﻣﯩﻐــﺎ ﺋــﯘﻻﺵ ﺋﯧﻠﯩــﭗ ﺑﺎﺭﯨــﺪﯨﻐﺎﻥ ﺑﻮﻟــﯘﭖ ﺋﯘﻧﯩــﯔ ﺋﻪﻧــﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ:
public static IEnumerable Concat( this IEnumerable first, ;) IEnumerable second ﻛﯚﺭﯨﯟﯦﻠﯩﺸﻘﺎ ﺑﻮﻟﯩﺪﯗ Concat ،ﺋﺎﺭﻗﯩﻠﯩﻖ > IEnumerable
var italianCustomers = from c in customers where c.Country == Countries.Italy select c; var americanCustomers = from c in customers where c.Country == Countries.USA select c; var expr = italianCustomers.Concat(americanCustomers);
81
LINQﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ
www.udmish.cn
SequenceEqual ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﻳﻪﻧﻪ ﺑﯩــﺮ ﻗﻮﻟﻠﯩﻨﯩــﺸﭽﺎﻥ ﻣﻪﺷــﻐﯘﻻﺗﭽﻰ ﺑﻮﻟــﯘﭖSequenceEqual ، ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﯗﻟﻐﺎﻥ:
public static bool SequenceEqual( this IEnumerable first, IEnumerable second); public static bool SequenceEqual( this IEnumerable