Download as pdf
Download as pdf
You are on page 1of 91

www.udmish.

cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 1
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪2‬‬

‫ﻣﯘﻧﺪﻩﺭﯨﺠﻪ‬

‫ﺋﺎﺗﺎﻟﻐﯘﻻﺭ ﺋﯩﺰﺍﮬﺎﺗﻰ ‪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 .................................................................‬‬


‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪3‬‬

‫‪) 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‬‬


‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪4‬‬

‫‪78 ............................................................................... DefaultIfEmpty‬‬

‫ﺑﺎﺷﻘﺎ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ ‪80 .............................................................................‬‬

‫‪) Concat‬ﺋﯘﻻﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ( ‪80 .................................................................‬‬

‫‪81 ............................................................................... SequenceEqual‬‬

‫ﻛﯧﭽﯩﻜﺘﯜﺭﯛﻟﻤﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻨﯩﺸﻰ ﯞﻩ ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ ﭼﺎﺭﯨﺴﻰ ‪82 .........................‬‬

‫ﻛﯧﭽﯩﻜﺘﯜﺭﯛﻟﻤﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻨﯩﺸﻰ ‪82 .....................................................‬‬

‫ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ ﭼﺎﺭﯨﺴﻰ ‪84 .......................................................................‬‬

‫ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ‪85 ...................................................................‬‬

‫‪ ToArray‬ﺑﯩﻠﻪﻥ ‪86 ........................................................................ ToList‬‬

‫‪88 ................................................................................. ToDictionary‬‬

‫‪89 .................................................................................... ToLookup‬‬

‫‪ OfType‬ﺑﯩﻠﻪﻥ ‪91 ........................................................................... Cast‬‬


‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪5‬‬

‫ﺋﺎﺗﺎﻟﻐﯘﻻﺭ ﺋﯩﺰﺍﮬﺎﺗﻰ‬
‫ﻣﻪﺯﻛــﯘﺭ ﻛﯩﺘــﺎﺑﻨﻰ ﺋﻮﻗــﯘﺵ ﺟﻪﺭﻳﺎﻧﯩــﺪﺍ ﭘــﺎﺕ‪-‬ﭘــﺎﺕ ﻛﯜﻟــﯜﭖ ﺗﯘﺭﯨــﺪﯨﻐﺎﻧﻠﯩﻘﯩﯖﯩﺰﻏﺎ ﺋﯩــﺸﻪﻧﭽﯩﻢ ﻛﺎﻣﯩــﻞ‪.‬‬
‫ﺋﻪﺳـــﻠﯩﺪﻩ ﺋﺎﺗـــﺎﻟﻐﯘﻻﺭ ﺋﯩﺰﺍﮬـــﺎﺗﻰ ﻣﻪﻥ ﻳﺎﺯﯨـــﺪﯨﻐﺎﻥ ﻣﻪﺯﻣـــﯘﻥ ﺋﻪﻣﻪﺱ ﺋﯩـــﺪﻯ‪ ،‬ﻟـــﯧﻜﯩﻦ ﻛﻮﻣﭙﯩﻴـــﯘﺗﯧﺮ‬
‫ﺳﺎﮬﻪﺳــﯩﺪﯨﻜﻰ ﻛﻪﺳــﭙﯩﻲ ﺋﺎﺗــﺎﻟﻐﯘﻻﺭﻧﻰ ﺋﺎﺗــﺎﻟﻐﯘ ﺋﯩﺰﺍﮬــﺎﺕ ﻟــﯘﻏﻪﺗﻠﯩﺮﯨﻤﯩﺰﺩﯨﻦ ﺗﻮﻟــﯘﻕ ﺗﺎﭘﺎﻻﻳــﺪﯨﻐﺎﻥ‬
‫ﺑﻮﻟﯘﺷـــﯩﻤﯩﺰﻏﺎ ﻳﻪﻧﻪ ﺑﯩـــﺮ ﻣﻪﺯﮔﯩـــﻞ ﻛﯧﺘﯩـــﺪﯨﻐﺎﻥ ﺑﻮﻟﻐﺎﭼﻘـــﺎ‪ ،‬ﺑﯩـــﺮ ﻗﯩـــﺴﯩﻢ ﻛﻪﺳـــﭙﻰ ﺋﺎﺗـــﺎﻟﻐﯘﻻﺭﻧﻰ‬
‫ﺟﯚﻳﻠﯜﺷــﯩﻤﯩﺰﮔﻪ ﺗــﻮﻏﺮﺍ ﻛﻪﻟــﺪﻯ‪ .‬ﺷــﯘﯕﺎ ﻛﯩﺘــﺎﺏ ﻣﻪﺯﻣﯘﻧﯩــﺪﺍ ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﺳــﯚﺯﻟﻪﺭﻧﻰ ﺋــﯘﭼﺮﺍﺗﻘﯩﻨﯩﯖﯩﺰﺩﺍ‬
‫ﻛﯜﻟﮕﻪﭺ ﺗﻮﻏﺮﺍ ﭼﯜﺷﯩﻨﻪﺭﺳﯩﺰ‪ .‬ﺋﺎﺗﺎﻟﻐﯘ ﺗﻪﺭﺟﯩﻤﻪ ﺧﯩﺰﻣﯩﺘﯩﺪﻩ ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﭘﯩﻜﯩﺮﻟﻪﻧﻰ ﺑﻪﺭﮔﻪﻥ ﺋﯚﻣﻪﺭﺟـﺎﻥ‬
‫ﺋﺎﺑﺪﯗﺭﺍﺧﻤﺎﻥ )ﺋﯘﭼﻘﯘﻥ( ﺋﻪﭘﻪﻧﺪﯨﮕﻪ ﻛﯚﭖ ﺗﻪﺷﻪﻛﻜﯜﺭ‪.‬‬

‫ﻛﯚﭘﻤﺎﺱ \ ﻛﯚﭘﻤﺎﺳﻠﯩﻖ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ‪ ،generic :‬ﺧﻪﻧﺰﯗﭼﯩﺴﻰ‪ 泛型 :‬ﺑﻮﻟـﯘﭖ‪ ،‬ﺋﻮﺭﺗـﺎﻕ ﺗﯩﭙﻠﯩـﭗ‪،‬‬


‫ﮬﻪﻣﻤﯩــﮕﻪ ﻣــﺎﺱ ﻛﯧﻠﯩــﺪﯨﻐﺎﻥ ﺩﯦــﮕﻪﻥ ﻣﻪﻧﯩﻠﻪﺭﻧــﻰ ﺑﯧﺮﯨــﺪﯗ‪ .‬ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ ﻧﯘﺧﺘﯩــﺴﯩﺪﯨﻦ ﭼﯜﺷــﻪﻧﮕﻪﻧﺪﻩ‪،‬‬
‫‪ generic‬ﺗﯩــﭗ ﺑﻮﻟــﺴﺎ ﻛﻮﻧﻜﺮﯦــﺖ ﺑﯩــﺮ ﺗﯩﭙﻨــﻰ ﻛﯚﺭﺳــﻪﺗﻤﻪﻱ ﺑﻪﻟﻜــﻰ ﺗﯩﭙــﻰ ﻣﻪﺷــﻐﯘﻻﺗﻘﺎ ﻗﺎﺗﻨﺎﺷــﻘﯘﭼﻰ‬
‫ﻛﻮﻧﻜﺮﯦﺖ ﺗﯩﭗ ﺗﻪﺭﯨﭙﯩﺪﯨﻦ ﺑﻪﻟﮕﯩﻠﯩﻨﯩﺪﯨﻐﺎﻥ ﺋﯧﻨﯩﻘﺴﯩﺰ‪ ،‬ﮬﻪﻣﻤﯩﮕﻪ ﻣـﺎﺱ ﻛﯧﻠﯩـﺪﯨﻐﺎﻥ ﺗﯩـﭗ ﺑﻮﻟﻐﺎﭼﻘـﺎ‪،‬‬
‫ﺋﯘﻧﯩﯔ ﮬﻪﻣﻤﯩﮕﻪ ﻣـﺎﺱ ﻛﯧﻠﯩـﺪﯨﻐﺎﻥ ﺋﺎﻻﮬﯩـﺪﯨﻠﯧﻜﯩﻨﻰ ﮔﻪﯞﺩﯨﻠﻪﻧـﺪﯛﺭﯛﺵ ﻳﯜﺯﯨـﺴﯩﺪﯨﻦ ﺋﯘﻧﯩـﯔ ﺳـﯜﭘﻪﺕ‬
‫ﺷﻪﻛﻠﻰ »ﻛﯚﭘﻤﺎﺱ«‪ ،‬ﺋﯩﺴﯩﻢ ﺷﻪﻛﻠﻰ »ﻛﯚﭘﻤﺎﺳﻠﯩﻖ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ‪.‬‬

‫ﻛــﻮﺩ ﻗــﺎﭘﭽﯘﻗﻰ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩــﺴﻰ‪ ،Code Container :‬ﺧﻪﻧﺰﯗﭼﯩــﺴﻰ‪ 代码容器 :‬ﺑﻮﻟــﯘﭖ‪ ،‬ﻣﻪﻟــﯘﻡ‬


‫ﻛــﻮﺩﻻﺭﻧﻰ ﺋﯚﺯﯨــﺪﻩ ﺋﯧﻠﯩــﭗ ﻳﯜﺭﻩﻟﻪﻳــﺪﯨﻐﺎﻥ ﻛــﻮﺩ ﺑــﯚﻟﯧﻜﯩﻨﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ‪ Container .‬ﻳﻪﻧــﻰ ‪容器‬‬
‫ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﺳﺎﮬﻪﺳﯩﺪﻩ ﻛﯚﭖ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯨﻐﺎﻥ ﺋﺎﺗﺎﻟﻐﯘ ﺑﻮﻟﯘﭖ‪ ،‬ﺑﯩﺮ ﺗﯜﺭﻛﯜﻡ ﻧﻪﺭﺳﯩﻠﻪﻧﻰ ﺋﯚﺯﯨـﺪﻩ ﺗﯘﺗـﯘﭖ‬
‫ﺗﯘﺭﺍﻻﻳﺪﯨﻐﺎﻥ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﻰ ﻛﯚﭘﯜﺭﻩﻙ ﻣﯘﺷﯘ ﺳﯚﺯ ﺑﯩﻠﻪﻥ ﺋﺎﺗﺎﻳﺪﯗ‪ .‬ﻣﻪﺳـﯩﻠﻪﻥ‪Control Container ،‬‬
‫)ﻛﻮﻧﺘﺮﻭﻝ ﻗﺎﭘﭽﯘﻗﻰ( ﺩﯦﮕﻪﻧﺪﻩﻙ‪ .‬ﺑﯘ ﺧﯩﻞ ﺋﺎﻻﮬﯩـﺪﯨﻠﯩﻜﻨﻰ ﺋﯩﭙـﺎﺩﯨﻠﻪﺵ ﺋﯜﭼـﯜﻥ »ﻛـﻮﺩ ﺳـﺎﻧﺪﯗﻗﻰ«‪،‬‬
‫»ﻛﻮﺩ ﺋﯧﻠﯩﭗ ﻳﯜﺭﮔﯜﭺ« ﺩﯦﮕﻪﻧﺪﻩﻙ ﺑﯩﺮ ﻗﯩﺴﯩﻢ ﺳـﯚﺯ ﺑﯩﺮﯨﻜﻤﯩﻠﯩﺮﻧـﻰ ﺋـﻮﻳﻼﭖ ﺑـﺎﻗﺘﯩﻢ‪ ،‬ﻟـﯧﻜﯩﻦ »ﻛـﻮﺩ‬
‫ﻗﺎﭘﭽﯘﻗﻰ« ﺩﻩﭖ ﺋﺎﺗﺎﺵ ﺋﻪﯓ ﻣﯘﯞﺍﭘﯩﻖ ﺗﯘﻳﯘﻟﺪﻯ‪.‬‬

‫ﭼـﺎﻗﯩﺮﻏﯘ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩـﺴﻰ‪ ،callback :‬ﺧﻪﻧﺰﯗﭼﯩـﺴﻰ‪ 回调 :‬ﺑﻮﻟــﯘﭖ‪ ،‬ﭼـﺎﻗﯩﺮﯨﺶ ﺩﯦـﮕﻪﻥ ﻣﻪﻧﯩــﺪﻩ‪.‬‬


‫ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺪﺍ ﺑﯩﺮ ﺩﺍﻧﻪ ‪ callback‬ﻣﻪﻟﯘﻡ ﻛﻮﺩ ﺑﯚﻟﯩﻜﯩﮕﻪ ﺗﻮﻏﯘﺭﻻﻧﻐﺎﻥ ﺋﯩـﺴﺘﺮﯦﻠﻜﯩﻐﺎ ﺋﯘﻻﻧﻐـﺎﻥ ﺑﻮﻟﯩـﺪﯗ‪.‬‬
‫‪ callback‬ﻧﻰ ﺋﯩﺠـﺮﺍ ﻗﯩﻠﯩـﺶ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﺋـﯘ ﺗﻮﻏﯘﺭﻻﻧﻐـﺎﻥ ﻛـﻮﺩ ﺑـﯚﻟﯧﻜﯩﻨﻰ ﺋﯩﺠـﺮﺍ ﻗﯩﻠﻐﯩﻠـﻰ ﺑﻮﻟﯩـﺪﯗ‪.‬‬
‫ﺩﯦﻤﻪﻙ ﺋﯘ ﺋﻪﺷﯘ ﻛﻮﺩ ﺑﯚﻟﯧﻜﯩﻨﯩـﯔ ﭼﺎﻗﯩﺮﻏﯘﭼﯩـﺴﻰ‪ ،‬ﺷـﯘﯕﺎ ﺋـﯘ »ﭼـﺎﻗﯩﺮﻏﯘ«‪ .‬ﺑـﯘ ﻣﯘﺷـﯘﻧﺪﺍﻕ ﺋﺎﺗﺎﺷـﻘﺎ‬
‫ﻳﯧﺘﻪﺭﻟﯩﻚ ﺋﺎﺳﺎﺱ ﺑﯩﻠﯩﻨﺪﻯ‪.‬‬

‫ﺩﻩﺳــﺘﻪ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩــﺴﻰ‪ ،stack :‬ﺧﻪﻧﺰﯗﭼﯩــﺴﻰ‪ 栈 :‬ﺑﻮﻟــﯘﭖ‪ ،‬ﺷــﻪﻳﺌﯩﻠﻪﺭﻧﯩﯔ ﺋﯜﺳــﺘﯩﻤﯘ‪-‬ﺋﯜﺳــﺘﻰ‬


‫ﺗﯩﺰﯨﻠﻐﺎﻥ ﺩﻩﺳﺘﯩﺴﯩﻨﻰ ﻛﯚﺭﺳﯩﺘﯩﺪﯗ‪ .‬ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺪﯨﻜﻰ ‪ stack‬ﺑﻮﻟﺴﺎ ﺑﯩﺮ ﺧﯩﻞ ﺋﺎﻻﮬﯩﺪﻩ ﺳﺎﻧﻠﯩﻖ ﻣﻪﻟﯘﻣﺎﺕ‬
‫ﻗﯘﺭﯗﻟﻤﯩﺴﻰ ﺑﻮﻟـﯘﭖ‪ ،‬ﺋﯘﻧﯩـﯔ ﻗﯘﺭﯗﻟﻤﯩـﺴﻰ ﺧـﯘﺩﺩﻯ ﺗﻪﺧـﺴﻪ ﺗﯩﺰﻏﺎﻧﻐـﺎ ﺋﻮﺧـﺸﺎﻳﺪﯗ‪ .‬ﻳﻪﻧـﻰ‪ ،‬ﺗﻪﺧـﺴﯩﻠﻪﺭ‬
‫ﺑﯩﺮﯨﻨﯩــﯔ ﺋﯜﺳــﺘﯩﮕﻪ ﺑﯩــﺮ ﻗﻮﻳﯘﻟﯩــﺪﯗ‪ .‬ﺋــﯘﻻﺭﻧﻰ ﺋــﯧﻠﯩﺶ ﺋﯜﭼــﯜﻥ ﺋﻪﯓ ﺗﯚﭘﯩــﺪﯨﻦ ﺑﯩــﺮ‪-‬ﺑﯩــﺮﻟﻪﭖ ﺋــﯧﻠﯩﺶ‬
‫ﻛﯧﺮﻩﻙ‪ ،‬ﺩﯦﻤﻪﻙ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﺪﺍ ﺗﯩﺰﯨﻠﻐﯩﻨﻰ ﺋﻪﯓ ﺑﺎﺷﺘﺎ ﺋﯧﻠﯩﻨﯩﺪﯗ‪ ،‬ﺋﻪﯓ ﺑﺎﺷﺘﺎ ﺗﯩﺰﯨﻠﻐﯩﻨﻰ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨـﺪﺍ‬
‫ﺋﯧﻠﯩﻨﯩﺪﯗ‪ .‬ﺑﯘ ﺟﻪﺭﻳﺎﻧﻨﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺭﻩﺳﯩﻤﺪﯨﻜﯩﺪﻩﻙ ﺋﯩﭙﺎﺩﯨﻠﻪﺵ ﻣﯘﻣﻜﯩﻦ‪:‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪6‬‬

‫ﺋﻪﯓ ﻛﯧﻴﯩﻦ ﺗﯩﺰﯨﻠﻐﺎﻥ ﺗﻪﺧﺴﻪ‬

‫ﺋﻪﯓ ﺑﯘﺭﯗﻥ ﺗﯩﺰﯨﻠﻐﺎﻥ ﺗﻪﺧﺴﻪ‬

‫ﺷﯘﯕﺎ ﺑﯘ ﺧﯩﻞ ﺳﺎﻧﻠﯩﻖ ﻣﻪﻟﯘﻣﺎﺕ ﻗﯘﺭﯗﻟﻤﯩﺴﻰ ﺩﻩﺳﺘﻪ ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ‪.‬‬

‫ﺋﯚﻣﯜﺭ – ﺋﯧﻨﮕﻠﯩﺰﭼﯩـﺪﺍ‪ ،lifetime :‬ﺧﻪﻧﺰﯗﭼﯩـﺪﺍ‪ 生命周期 :‬ﺑﻮﻟـﯘﭖ‪ ،‬ﺋﯚﻣـﯜﺭﻯ ﺩﯦـﮕﻪﻥ ﻣﻪﻧﯩـﺪﻩ‪ .‬ﺋـﯘ‬
‫ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺪﺍ ﻣﻪﻟﯘﻡ ﺋﯚﺯﮔﻪﺭﮔﯜﭼﻰ ﻣﯩﻘـﺪﺍﺭﻧﯩﯔ ﺋـﯚﺯﻯ ﺗﯘﺭﻏـﺎﻥ ﻛـﻮﺩ ﺑﯚﻟﯩﻜﯩـﺪﻩ ﺋﯜﻧﯜﻣﻠـﯜﻙ ﺑﻮﻻﻻﻳـﺪﯨﻐﺎﻥ‬
‫ﯞﺍﻗﯩــﺖ ﺋــﯘﺯﯗﻧﻠﯩﻘﯩﻨﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ‪ .‬ﻣﻪﺳــﯩﻠﻪﻥ‪ ،‬ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﭘﺮﻭﮔﺮﺍﻣﻤﯩــﺪﺍ ﺋﻮﺧــﺸﯩﻤﯩﻐﺎﻥ ﺋﻮﺭﯗﻧــﺪﺍ‬
‫ﺋﯧﻨﯩﻘﻼﻧﻐﺎﻥ ﺋﯚﺯﮔﻪﺭﮔﯜﭼﻰ ﻣﯩﻘﺪﺍﺭﻻﺭﻧﯩﯔ ﺋﯜﻧﯜﻣﻠﯜﻙ ﻣﻪﺯﮔﯩﻠﻰ ﺋﻮﺧﺸﺎﺵ ﺑﻮﻟﻤﺎﻳﺪﯗ‪.‬‬
‫‪public class MisalClass ‬‬
‫‪{ ‬‬
‫‪    public int ozgerguchi1 = 1; ‬‬
‫‪     ‬‬
‫‪    public int misalFun() ‬‬
‫‪   { ‬‬
‫‪        int ozgerguchi2 = ozgerguchi1 + 1 ; ‬‬
‫‪        return ozgerguchi2; ‬‬
‫‪   } ‬‬
‫‪} ‬‬

‫ﻳــﯘﻗﯩﺮﯨﻘﻰ ﻛــﻮﺩﺩﺍ ‪ ozgerguchi1‬ﻧﯩــﯔ ﺋﯜﻧﯜﻣﻠــﯜﻙ ﻣﻪﺯﮔﯩﻠــﻰ ‪ MisalClass‬ﻧﯩﯖﻜــﻰ ﺑﯩــﻠﻪﻥ ﺋﻮﺧــﺸﺎﺵ‬


‫ﺑﻮﻟﯘﭖ‪ MisalClass ،‬ﻣﻪﯞﺟﯘﺗﻼ ﺑﻮﻟﯩـﺪﯨﻜﻪﻥ ﺋﯘﻣـﯘ ﻣﻪﯞﺟـﯘﺕ ﺑﻮﻟـﯘﭖ ﺗﯘﺭﺍﻻﻳـﺪﯗ‪ ozgerguchi2 .‬ﻧﯩـﯔ‬
‫ﺋﯜﻧﯜﻣﻠﯜﻙ ﻣﻪﺯﮔﯩﻠﻰ ﻗﯩﺴﻘﯩﺮﺍﻕ ﺑﻮﻟـﯘﭖ‪ misalFun ،‬ﻓﯘﻧﻜﯩﺴﯩﻴﯩـﺴﯩﻨﯩﯔ ﺋﯩﺠﺮﺍﺳـﻰ ﺑﺎﺷﻠﯩﻨﯩـﺸﻰ ﺑﯩﻠﻪﻧـﻼ‬
‫ﺋﯜﻧﯜﻡ ﺑﻮﻟﯘﺷﻘﺎ ﺑﺎﺷﻼﭖ‪ ،‬ﺋﯩﺠﺮﺍ ﺗﺎﻣﻼﻣﻼﻧﻐﺎﻧﺪﺍ ﺋﯜﻧﯜﻣﺴﯩﺰﻟﯩﻨﯩﺪﯗ‪ .‬ﺋﯚﺯﮔﻪﺭﮔـﯜﭼﻰ ﻣﯩﻘـﺪﺍﺭﻻﺭﻧﯩﯔ ﺑـﯘ ﺧﯩـﻞ‬
‫ﺧﺎﺳﻠﯩﻘﯩﻨﻰ ﺋﯘﻧﯩﯔ »ﺋﯚﻣﺮﻯ« ﺩﻩﭖ ﺋﺎﺗﺎﺵ ﻣﯘﯞﺍﭘﯩﻖ ﺑﯩﻠﯩﻨﺪﻯ‪.‬‬

‫‪ ،(Intermediate‬ﺧﻪﻧﺰﯗﭼﯩــﺴﻰ ‪ 中间语言‬ﺑﻮﻟــﯘﭖ‪،‬‬ ‫ﺋﯚﺗﻜــﯜﻧﭽﻰ ﻛــﻮﺩ‪ -‬ﺋﯩﻨﮕﻠﯩﺰﭼﯩــﺴﻰ ‪Code)IL‬‬


‫‪ .NET‬ﺋﺎﺋﯩﻠﯩﺴﯩﺪﯨﻜﻰ ﺗﯩﻠﻼﺭﺩﺍ ﻳﯧﺰﯨﻠﻐـﺎﻥ ﻛـﻮﺩﻻﺭ ﺋﺎﺧﯩﺮﯨـﺪﺍ ﮬﻪﻣﻤﯩـﺴﯩﮕﻪ ﺋﻮﺭﺗـﺎﻕ ﺑﻮﻟﻐـﺎﻥ ‪ IL‬ﺗﯩﻠﯩﻐـﺎ‬
‫ﺋﺎﻳﻼﻧــﺪﯗﺭﯗﻟﯘﭖ‪ ،‬ﮬﻪﻗﯩﻘــﻰ ﺋﯩﺠــﺮﺍ ﺑﻮﻟﻐﺎﻧــﺪﺍ ﺋﯘﻣــﯘ ﻳﻪﻧﻪ ﻣﺎﺷــﯩﻨﺎ ﺗﯩﻠﯩﻐــﺎ ﺋﺎﻳﻠﯩﻨﯩــﺪﯗ‪ .‬ﺋﻪﻣﻪﻟﯩﻴﻪﺗــﺘﻪ‪C# ،‬‬
‫ﺑﯩﻠﻪﻥ ‪ VB.NET‬ﻳﯧﺰﯨﻠﻐﺎﻥ ﻛـﻮﺩﻻﺭﻧﻰ ﺋـﺎﺭﻻﺵ ﺋﯩﺸﻠﯩﺘﯩـﺸﻜﻪ ﻣـﯘﻣﻜﯩﻦ ﺑﻮﻟﯩـﺪﯨﻐﺎﻧﻠﯩﻘﯩﻨﯩﯔ ﺳـﻪﯞﻩﺑﯩﻤﯘ‬
‫ﺷﯘ‪ .‬ﺋﯘ ﺧﺎﺭﺍﻛﺘﯧﺮﯨﮕﻪ ﺋﺎﺳﺎﺳﻪﻥ »ﺋﯚﺗﻜﯜﻧﭽﻰ ﻛﻮﺩ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪7‬‬

‫ﺗﯩﻠﻼﺭﻏﺎ ﺋﻮﺭﺗﺎﻕ ﺋﯩﺠﺮﺍ ﺳﯘﭘﯩـﺴﻰ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩـﺴﻰ ‪ ،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‬ﺑﻮﻟــﯘﭖ‪ ،‬ﭘﺮﻭﮔﺮﺍﻣﻤﯩــﺪﺍ ﻣﻪﻟــﯘﻡ ﻛﻮﺩﻧﯩــﯔ ﺋﯩﺠــﺮﺍ ﺑﻮﻟــﯘﺵ‬


‫ﺋﺎﻻﮬﯩــﺪﯨﻠﯧﻜﯩﻨﻰ ﯞﻩ ﺧﯩــﺰﻣﻪﺕ ﭘﯩﺮﯨﻨــﺴﯩﭙﯩﻨﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ‪ .‬ﺩﯦــﻤﻪﻙ ﺋــﯘ ﺷــﯘ ﭘﺮﻭﮔﺮﺍﻣﻤﯩﻨﯩــﯔ‬
‫ﺧﯘﻟﻘﻰ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪8‬‬

‫ﺧﺎﺱ ﺳﯚﺯ – ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ‪ ،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‬ﺟﻪﺭﻳﺎﻧﯩﻨﯩــﯔ ﺋــﯘﻧﻰ‬
‫ﺋﯩــﺸﻠﻪﺗﻜﯜﭼﻰ )ﺳﯜﺭﯛﺷــﺘﯜﺭﮔﯜﭼﻰ( ﺩﯨــﻦ ﭘﻪﺭﻗﻠﯩﻨﯩــﺪﯨﻐﺎﻥ ﻣﯘﺳــﺘﻪﻗﯩﻞ ﺟﻪﺭﻳــﺎﻥ ﺑﻮﻟﻐــﺎﻧﻠﯩﻘﻰ ﻛــﯚﺯﺩﻩ‬
‫ﺗﯘﺗﯘﻟــﯘﭖ »ﺳﯜﺭﯛﺷــﺘﯜﺭ« ﺳــﯚﺯﯨﮕﻪ »ﯛﻙ« ﺳــﯚﺯ ﻳﺎﺳــﯩﻐﯘﭼﻰ ﻗﻮﺷﯘﻣﭽﯩــﺴﯩﻨﻰ ﻗﻮﺷــﯘﺵ ﺋــﺎﺭﻗﯩﻠﯩﻖ‬
‫»ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ« ﺩﻩﭖ ﺋﯧﻠﯩﻨﺪﻯ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪9‬‬

‫ﻛﯩﺘـﺎﺏ ﻣﻪﺯﻣﯘﻧﯩـﺪﺍ‪ SQL ،‬ﺳﯜﺭﯛﺷـﺘﯜﺭﯛﻛﻰ )‪ LINQ ،(SQL Query‬ﺳﯜﺭﯛﺷـﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨـﺴﻰ ) ‪LINQ‬‬


‫‪ (Query‬ﻗﺎﺗــــﺎﺭﻟﯩﻖ‬ ‫‪ ،(Query‬ﺳﯜﺭﯛﺷــــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨــــﺴﻰ)‪Expression‬‬ ‫‪Expression‬‬
‫»ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ« ﻧﻰ ﺋﯚﺯ ﺋﯩﭽﯩﮕﻪ ﺋﺎﻟﻐﺎﻥ ﺋﺎﺗﺎﻟﻐﯘﻻﺭﻧﻰ ﺋﯘﭼﺮﯨﺘﯩﭗ ﺗﯘﺭﯨﺴﯩﺰ‪ .‬ﺋﯘﻻﺭﻏـﺎ ﺋـﺎﻳﺮﯨﻢ ﺋﯩﺰﺍﮬـﺎﺕ‬
‫ﺑﯧﺮﯨﻠﻤﯩﺪﻯ‪.‬‬

‫ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺋﺎﺗﺎﻟﻐﯘﻻﺭﻧﯩﯔ ﺗﻪﺭﺟﯩﻤﯩﺴﯩﻼ ﺑﯧﺮﯨﻠﺪﻯ‬

‫ﺧﻪﻧﺰﯗﭼﯩﺴﻰ‬ ‫ﺋﯩﻨﮕﻠﯩﺰﭼﯩﺴﻰ‬ ‫ﺋﯘﻳﻐﯘﺭﭼﯩﺴﻰ‬

‫‪静态层‬‬ ‫‪Static Layer‬‬ ‫ﺗﯘﺭﻏﯘﻥ ﻗﻪﯞﻩﺕ‬


‫‪谓语‬‬ ‫‪Predicate‬‬ ‫ﻛﯚﺭﺳﻪﺗﻤﻪ‬
‫‪强类型语言‬‬ ‫‪Strongly Typed Language‬‬ ‫ﻗﺎﺗﺘﯩﻖ ﺗﯩﭙﻠﯩﻖ ﺗﯩﻞ‬
‫‪类型推导‬‬ ‫‪Type Inference‬‬ ‫ﺗﯩﭗ ﻛﻪﻟﺘﯜﺭﯛﻟﻤﯩﺴﻰ‬
‫‪Projection‬‬ ‫ﺋﻪﻣﻪﻟﯩﻴﻪﺷﺘﯜﺭﯛﺵ‬
‫‪Enumerate‬‬ ‫ﭼﺎﺭﻻﺵ‬
‫‪值类型‬‬ ‫‪Value Type‬‬ ‫ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﺗﯩﭗ‬
‫‪引用类型‬‬ ‫‪Reference Type‬‬ ‫ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺗﯩﭗ‬

‫ﺋﻪﺳﻜﻪﺭﺗﯩﺶ‪ :‬ﻳﯘﻗﯩﺮﯨﻘﻰ ﺋﺎﺗﺎﻟﻐﯘﻻﺭ ﺑﯩﺮﺩﻩﻙ ﺑﯩﺮ ﻗﯩﺴﯩﻢ ﻛﻪﺳﯩﭙﺪﺍﺷﻼﺭ ﺑﯩـﻠﻪﻥ ﭘﯩﻜﯩﺮﻟﯩـﺸﯩﺶ ﺋﺎﺳﺎﺳـﯩﺪﺍ‬
‫ﺗﻪﺭﺟﯩﻤﻪ ﻗﯩﻠﯩﻨﻐﺎﻥ‪ ،‬ﻣﯘﺷﯘ ﻛﯩﺘﺎﺑﺘﯩﻦ ﺑﺎﺷﻘﺎ ﮬﻪﺭﻗﺎﻧﺪﺍﻕ ﻣﺎﺗﯧﺮﻳﺎﻟﻼﺭﺩﯨﻜﻰ ﺋﻮﺧﺸﺎﺵ ﺋﺎﺗﺎﻟﻐﯘﻻﺭﻏﺎ ﺋﺎﺳﺎﺱ‬
‫ﺑﻮﻻﻟﻤﺎﻳــﺪﯗ‪ .‬ﮬﻪﻡ ﻣﻪﺯﻛــﯘﺭ ﺗﻪﺭﺟﯩﻤﯩــﻠﻪﺭ ﺳــﻪﯞﻩﺑﻠﯩﻚ ﻛﯧﻠﯩــﭗ ﭼﯩﻘﻘــﺎﻥ ﮬﻪﺭﻗﺎﻧــﺪﺍﻕ ﻣﻪﺳــﺌﯘﻟﯩﻴﻪﺗﻨﻰ‬
‫ﺋﯜﺳﺘﯩﻤﯩﺰﮔﻪ ﺋﺎﻟﻤﺎﻳﻤﯩﺰ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪10‬‬

‫ﺋﯩﻜﻜﯩﻨﭽﻰ ﺑﺎﺏ ‪ 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‬ﺑﻮﻟﻐﺎﻥ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻻﺭﻏﯩﻼ ﻣﻪﺷﻐﯘﻻﺕ ﺑﯩﺠﯩﺮﻩﻟﻪﻳﺪﯗ‪.‬‬


‫ﺋﻪﮔﻪﺭ ﺋﯘﻧﻰ ﺑﺎﺷﻘﺎ ﺗﯩﭙﻠﯩﻖ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻻﺭﻏﺎ ﻗﻮﻟﻼﻧﻤﺎﻗﭽﻰ ﺑﻮﻟﺴﺎﻕ‪ ،‬ﭼﻮﻗﯘﻡ ﺷﯘ ﺗﯩﭙﻘﺎ ﺧﺎﺱ ﻣﯧﺘﻮﺩ‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪11‬‬

‫‪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>( T a, T b ) where T : IComparable<T> { ‬‬
‫‪    if (a.CompareTo( b ) < 0) return a; ‬‬
‫‪    else return b; ‬‬
‫‪} ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪12‬‬

‫ﺋﻪﺳﻜﻪﺭﺗﯩﺶ‪ :‬ﮬﺎﺯﯨﺮ‪-‬ﺟﺎﯞﺍﺏ ﻛﻮﺩ‪-‬ﺗﻪﺭﺟﯩﻤﺎﻥ)‪ (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<int>( a, b ); ‬‬
‫ﺩﻩﻙ ﻳﺎﺯﺍﻻﻳﻤﯩﺰ‪.‬‬
‫ﺋﻪﻣــﺪﻯ‪ ،‬ﺑــﯘﺭﯗﻥ ﺗﯩــﭗ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺷــﻘﺎ ﺳــﻪﺭﭖ ﻗﯩﻠﯩــﭗ ﻳــﯜﺭﮔﻪﻥ ‪ CPU‬ﭼﯩﻘﯩﻤﻠﯩﺮﯨﻤﯩــﺰ ﺗﯧﺠﯩﻠﯩــﭗ‪،‬‬
‫ﭘﺮﻭﮔﺮﺍﻣﻤﯩﻤﯩــﺰ ﺗﯧﺨﯩﻤــﯘ ﺗﯧــﺰ ﺋﯩﺠــﺮﺍ ﺑﻮﻟﯩــﺪﯨﻐﺎﻥ ﺑﻮﻟﺪﯨــﺪﻩ‪ ....‬ﭼــﯜﻧﻜﻰ ﺑــﯘﻳﻪﺭﺩﻩ ﮬﯧﭽﻘﺎﻧــﺪﺍﻕ ﺗﯩــﭗ‬
‫ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﻰ ﻳﯜﺯ ﺑﻪﺭﻣﻪﻳﺪﯗ‪ .‬ﺋﯘﻧﯩﯔ ﺋﯜﺳﺘﯩﮕﻪ ﻛﻮﺩ‪-‬ﺗﻪﺭﺟﯩﻤـﺎﻥ ﺑﯧـﺮﯨﻠﮕﻪﻥ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻧﯩـﯔ‬
‫ﻗﯩﻤﻤﯩﺘﯩﮕﻪ ﺋﺎﺳﺎﺳﻪﻥ ﻛﯚﭘﻤﺎﺱ ﺗﯩﭗ ‪ T‬ﻧﯩﯔ ﺋﯧﻨﯩﻖ ﺗﯩﭙﯩﻨﻰ ﭘﻪﺭﻩﺯ ﻗﯩﻼﻻﻳﺪﯗ)ﺗﯩﭗ ﻛﻪﻟﺘﯜﺭﯛﻟﻤﯩـﺴﻰ ﺩﻩﭖ‬
‫ﺋﺎﺗﯩﻠﯩﺪﯗ(‪ .‬ﺷﯘﯕﺎ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩﻧﻰ ﺗﯧﺨﯩﻤﯘ ﺋﺎﺩﺩﯨﻴﻼﺷﺘﯘﺭﯗﭖ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻛﻤﯘ ﻳﺎﺯﺍﻻﻳﻤﯩﺰ‪:‬‬
‫‪int a = 5, b = 10; ‬‬
‫‪int c = Min( a, b ); ‬‬

‫ﺗﯩﭗ ﻛﻪﻟﺘﯜﺭﯛﻟﻤﯩﺴﻰ‪ :‬ﺗﯩﭗ ﻛﻪﻟﺘﯜﺭﯛﻟﻤﯩﺴﻰ ﺋﯩﻨﺘﺎﻳﯩﻦ ﻣﯘﮬﯩﻢ ﺋﯩﻘﺘﯩﺪﺍﺭ ﺑﻮﻟﯘﭖ‪ ،‬ﺋﯘ ﻛﻮﺩ‪-‬ﺗﻪﺭﺟﯩﻤـﺎﻧﻨﻰ‬
‫ﺗﯩﭙﻘﺎ ﺋﺎﻻﻗﯩﺪﺍﺭ ﺗﻪﭘﺴﯩﻠﯩﻲ ﺋﯩﺸﻼﺭﻏﺎ ﺑﯘﻳﺮﯗﭖ‪ ،‬ﺳﯩﺰﻧﻰ ﺗﯧﺨﯩﻤﯘ ﺋﺎﺑﺴﺘﺮﺍﻛﺖ ﻛﻮﺩ ﻳﯧﺰﯨﺶ ﺋﯩﻤﻜـﺎﻧﯩﻴﯩﺘﯩﮕﻪ‬
‫ﺋﯩﮕﻪ ﻗﯩﻠﯩﺪﯗ‪.‬‬

‫ﻛﯚﭘﻤﺎﺳــﻠﯩﻘﺘﯩﻦ ﭘﺎﻳــﺪﯨﻠﯩﻨﯩﭗ ﻛﯚﭘﻤــﺎﺱ ﻣﯧﺘــﻮﺩ ﺋﯧــﻨﯩﻘﻠﯩﻐﯩﻠﯩﻼ ﺑﻮﻟــﯘﭖ ﻗﺎﻟﻤــﺎﻱ‪ ،‬ﻳﻪﻧﻪ ﻛﯚﭘﻤــﺎﺱ ﺗــﯜﺭ‪،‬‬
‫ﺋﯧﻐﯩﺰﻻﺭﻧﯩﻤــﯘ ﺋﯧﻨﯩﻘﻠﯩﻐﯩﻠــﻰ ﺑﻮﻟﯩــﺪﯗ‪ .‬ﻛﯚﭘﻤﺎﺳــﻠﯩﻖ ﺋﯜﺳــﺘﯩﺪﻩ ﺗــﻮﺧﺘﯩﻠﯩﺶ ﺑــﯘ ﻛﯩﺘﺎﺑﻨﯩــﯔ ﺋﺎﺳﺎﺳــﻠﯩﻖ‬
‫ﻣﻪﻗــﺴﯩﺘﻰ ﺑﻮﻟﻤﯩﻐﺎﭼﻘــﺎ ﺗﻪﭘــﺴﯩﻠﯩﻲ ﺗﻮﺧﺘﺎﻟﻤــﺎﻱ‪ .‬ﻟــﯧﻜﯩﻦ‪ ،‬ﺷــﯘﻧﻰ ﻳﻪﻧﻪ ﺩﯦﮕﯩــﻢ ﻛﻪﻟــﺪﻯ‪ :‬ﻛﯚﭘﻤﺎﺳــﻠﯩﻘﻨﻰ‬
‫ﭼﯜﺷﻪﻧﻤﻪﻱ ﺗﯘﺭﯗﭖ ‪ LINQ‬ﻛﯚﺭﺳﯩﯖﯩﺰ ﺋﯚﺯﯨﯖﯩﺰﻧﻰ ﺭﺍﮬﻪﺕ ﮬﯧﺲ ﻗﯩﻼﻟﻤﺎﻳﺴﯩﺰ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪13‬‬

‫ﻣﯘﯞﻩﻗﻘﻪﺗﻠﻪﺭ‬
‫ﻣﯘﯞﻩﻗﻘﻪﺕ ﺩﯦﮕﯩﻨﯩﻤﯩـﺰ ﺑﯩـﺮ ﻳـﺎﻛﻰ ﺑﯩـﺮﺩﯨﻦ ﺋـﺎﺭﺗﯘﻕ ﻣﯧﺘﻮﺩﻧﯩـﯔ ﻗﺎﭘﻼﻧﻤـﺎ ﺗﯜﺭﯨـﺪﯨﻦ ﺋﯩﺒـﺎﺭﻩﺕ‪ .‬ﺋﯩﭽﻜـﻰ‬
‫ﻗﯩﺴﯩﻤﺪﺍ‪ ،‬ﺑﯩـﺮ ﺩﺍﻧﻪ ﻣـﯘﯞﻩﻗﻘﻪﺗﺘﻪ ﻣﯘﺷـﯘ ﻣـﯘﯞﻩﻗﻘﻪﺕ ﻗﺎﭘﻠﯩﻐـﺎﻥ ﻣﯧﺘﻮﺩﻻﺭﻏـﺎ ﻗﺎﺭﯨﺘﯩﻠﻐـﺎﻥ ﺋﯩـﺴﺘﯧﺮﯦﻠﻜﯩﻼﺭ‬
‫ﺗﯩﺰﻣﯩﺴﻰ ﺳﺎﻗﻠﯩﻨﯩﺪﯗ‪ .‬ﮬﻪﺭ ﺑﯩﺮ ﺋﯩﺴﺘﺮﯦﻠﻜﺎ ﺋﯚﺯﻯ ﺗﻮﻏﯘﺭﻻﻧﻐﺎﻥ ﻣﯧﺘﻮﺩﻧﻰ ﺋـﯚﺯ ﺋﯩﭽﯩـﮕﻪ ﺋﺎﻟﻐـﺎﻥ ﺗﯜﺭﯨﻨﯩـﯔ‬
‫ﭼﺎﻗﯩﺮﯨﻠﻤﯩﺴﯩﻐﺎ ﻣﺎﺱ ﻛﯧﻠﯩﺪﯗ‪.‬‬
‫ﮬﻪﺭﺑﯩﺮ ﻣﯘﯞﻩﻗﻘﻪﺕ ﺑﯩﺮ‪-‬ﻗﺎﻧﭽﻪ ﻣﯧﺘـﻮﺩﻧﻰ ﻗﺎﭘﻠﯩﻴﺎﻻﻳـﺪﯗ‪ .‬ﻟـﯧﻜﯩﻦ ﺑـﯘ ﭘﺎﺭﺍﮔﺮﺍﻓﺘـﺎ ﭘﻪﻗﻪﺕ ﺑﯩـﺮﻻ ﻣﯧﺘـﻮﺩﻧﻰ‬
‫ﻗﺎﭘﯩﻠﯩﻐﺎﻥ ﻣﯘﯞﻩﻗﻘﻪﺗﻠﻪﺭ ﻛﯚﭘﺮﻩﻙ ﻛﯚﯕـﯜﻝ ﺑﯚﻟﯩﻨﯩـﺪﯗ‪ .‬ﺋﺎﺑـﺴﺘﺮﺍﻛﺘﺮﺍﻕ ﻧﯘﺧﺘﯩـﺪﯨﻦ ﺋﯧﻠﯩـﭗ ﺋﯧﻴﺘـﺴﺎﻕ‪ ،‬ﺑـﯘ‬
‫ﺧﯩﻠــﺪﯨﻜﻰ ﻣــﯘﯞﻩﻗﻘﻪﺗﻠﻪﺭﻧﻰ »ﻛــﻮﺩ ﻗــﺎﭘﭽﯘﻗﻰ« ﻏــﺎ ﺋﻮﺧــﺸﯩﺘﯩﺶ ﻣــﯘﻣﻜﯩﻦ‪ .‬ﺑــﯘ ﻗــﺎﭘﭽﯘﻗﺘﯩﻜﻰ ﻛــﻮﺩﻧﻰ‬
‫ﺋﯚﺯﮔﻪﺭﺗﻜﯩﻠﻰ ﺑﻮﻟﻤﺎﻳﺪﯗ‪ .‬ﻟﯧﻜﯩﻦ ﺋﯘ ﭼﺎﻗﯩﺮﯨﻠﻤﺎ ﺩﻩﺳـﺘﯩﻠﯩﺮﯨﮕﻪ ﺋﻪﮔﯩـﺸﯩﭗ ﻳﯚﺗﻜﯩﻠﻪﻟﻪﻳـﺪﯗ ﮬﻪﻣـﺪﻩ ﺗـﺎﻛﻰ‬
‫ﺋــﯘﻧﻰ ﺋﯩــﺸﻠﯩﺘﯩﺶ ﺋﯧﮫﺘﯩﻴــﺎﺟﻰ ﻗﺎﻟﻤﯩﻐﺎﻧﻐــﺎ ﻗﻪﺩﻩﺭ ﻣﻪﯞﺟــﯘﺕ ﺑﻮﻟــﯘﭖ ﺗﯘﺭﺍﻻﻳــﺪﯗ‪ .‬ﺋﯘﻧﯩﯖــﺪﯨﻦ ﺑﺎﺷــﻘﺎ‪،‬‬
‫ﻣﯘﯞﻩﻗﻘﻪﺕ ﻳﻪﻧﻪ‪ ،‬ﺋﯚﺯﻯ ﻗﺎﭘﻠﯩﻐـﺎﻥ ﻣﯧﺘـﻮﺩﻧﻰ ﺋـﯚﺯ ﺋﯩﭽﯩـﮕﻪ ﺋﺎﻟﻐـﺎﻥ ﺗـﯜﺭﻧﻰ ﮬـﯧﭻ ﺑﻮﻟﻤﯩﻐﺎﻧـﺪﺍ ﺋﯚﺯﯨﻨﯩـﯔ‬
‫ﺋﯚﻣﺮﻯ ﺑﯩﻠﻪﻥ ﺗﻪﯓ ﻳﺎﺷﯩﻐﯘﺯﺍﻻﻳﺪﯗ‪.‬‬

‫ﻧﺎﻣﺴﯩﺰ ﻣﯧﺘﻮﺩ ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﻣﯘﯞﻩﻗﻘﻪﺗﻨﯩﯔ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﺴﯩﻐﺎ ﺋﺎﺳﺎﺳﻪﻥ ﺋﯚﺯﮔﻪﺭﺗﯩﻠﯩﭗ ﻗﯘﺭﯗﻟﻐﺎﻥ‪ .‬ﺋﯘﻧﯩﯖﻐـﺎ‬


‫ﺋﺎﺋﯩﺖ ﻣﻪﺯﻣﯘﻧﻼﺭ ﻛﯧﻴﯩﻨﻜﻰ ﭘﺎﺭﺍﮔﺮﺍﻓﺘـﺎ ﺳـﯚﺯﻟﯩﻨﯩﺪﯗ‪ .‬ﻣـﯘﯞﻩﻗﻘﻪﺗﺘﯩﻦ ﺑﯩﺮﻧـﻰ ﺋﯧـﻨﯩﻘﻼﺵ ﺋﻪﻣﻪﻟﯩﻴﻪﺗـﺘﻪ ﺷـﯘ‬
‫ﻣﯘﯞﻩﻗﻘﻪﺗﻨﯩﯔ ﺋﯚﺯﯨﻨﻰ ﻗﯘﺭﯨﺪﯨﻐﺎﻥ ﺗﯩﭙﺘﯩﻦ ﺑﯩﺮﻧﻰ ﺋﯧـﻨﯩﻘﻼﺵ ﺑﯩـﻠﻪﻥ ﺑـﺎﺭﺍﯞﻩﺭ‪ .‬ﻣـﯘﯞﻩﻗﻘﻪﺕ ﺋﯧﻨﯩﻘﻠﯩﻐﺎﻧـﺪﺍ‬
‫ﭼﻮﻗـــﯘﻡ ﺋﯘﻧﯩـــﯔ ﻣﯧﺘـــﻮﺩ ﺋﻪﻧﺪﯨﺰﯨـــﺴﯩﻨﻰ ﺗﻮﻟـــﯘﻕ ﺗﻪﻣﯩﻨﻠﯩـــﺸﻰ ﻛﯧـــﺮﻩﻙ‪ .‬ﻛـــﻮﺩ ‪ 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 ); ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪14‬‬

‫‪        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‬ﺑﻮﻟﺴﺎ ﺋﯚﺯﮔﻪﺭﺗﻜﯩﻤﯩﺰ ﻳﻮﻕ ﻣﯧﺘﻮﺩ‪:‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪15‬‬

‫ﻛﻮﺩ ‪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‬ﺩﯨﻜﯩـﺪﻩﻙ ﻛـﻮﺩﻻﺭﻧﻰ ﻳﯧﺰﯨـﺸﻨﯩﯔ ﺗﯧﺨﯩﻤـﯘ ﺋـﺎﺩﺩﯨﻲ‬
‫ﻳﻮﻟﻠﯩﺮﻯ ﺗﻪﻣﯩﻨﻠﻪﻧﮕﻪﻥ‪ .‬ﻣﻪﺳﯩﻠﻪﻥ‪:‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪16‬‬

‫ﻛﻮﺩ ‪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 ‬‬
‫‪); ‬‬
‫‪    } ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪17‬‬

‫‪ ‬‬
‫‪    void Run3() { ‬‬
‫‪        Repeat10Times( delegate( string text, int age ) { ‬‬
‫‪            Console.WriteLine( "{0} {1}", text, age ); ‬‬
‫‪        } ); ‬‬
‫‪    } ‬‬
‫‪    // … ‬‬
‫‪} ‬‬

‫‪ Enumerators‬ﯞﻩ ‪Yield‬‬
‫‪ C#‬ﺩﻩ ﭼـــﺎﺭﻻﺵ ﻣﻪﺷـــﻐﯘﻻﺗﯩﻨﻰ ﻗـــﻮﻟﻠﯩﺘﯩﺶ ﺋﯜﭼـــﯜﻥ ﺋﯩﻜﻜـــﻰ ﺩﺍﻧﻪ ﺋﯧﻐﯩـــﺰ ﺗﻪﻣﯩـــﻨﻠﻪﻧﮕﻪﻥ‪.‬‬ ‫‪1.x‬‬
‫‪ 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 ); ‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 18

    } 

 
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() { 
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪19‬‬

‫‪        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<T‬‬
‫ﯞﻩ >‪ IEnumerator<T‬ﺩﯨــﻦ ﺋﯩﺒــﺎﺭﻩﺕ ﻛﯚﭘﻤــﺎﺱ ﭼــﺎﺭﻻﺵ ﺋﯧﻐﯩﺰﻟﯩــﺮﻯ ﻛــﯚﭘﻪﻳﺘﯩﻠﮕﻪﻥ‪ .‬ﺑــﯘ ﺋﯧﻐﯩــﺰﻻﺭ‬
‫ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﯚﺯﯨﻤﯩﺰﻧﯩــﯔ ﺗﯩﭙﻠﯩــﺮﻯ ﺑﯩــﻠﻪﻥ ‪ object‬ﺗﯩﭙــﻰ ﺋﺎﺭﯨــﺴﯩﺪﯨﻜﻰ ﺋﺎﻟﻤﯩــﺸﯩﺶ ﺟﻪﺭﻳــﺎﻧﯩﻨﻰ‬
‫ﻗﯩــﺴﻘﺎﺭﺗﻘﯩﻠﻰ ﺑﻮﻟﯩــﺪﯗ‪ .‬ﺑــﯘ ﺋﯩﻘﺘﯩــﺪﺍﺭ ﭼــﺎﺭﻻﻧﻐﯘﭼﻰ ﻗﯩﻤﻤﻪﺗﻠﯩــﻚ ﺗﯩــﭗ ﺑﻮﻟﻐﺎﻧــﺪﺍ ﺗﯧﺨﯩﻤــﯘ ﺋﯜﻧــﯜﻣﯩﻨﻰ‬
‫ﻛﯚﺭﺳﯩﺘﯩﺪﯗ‪ .‬ﭼﯜﻧﻜﻰ ‪ CPU‬ﺳـﻪﺭﭘﯩﻴﺎﺗﻰ ﺗﻪﻟﻪﭖ ﻗﯩﻠﯩـﺪﯨﻐﺎﻥ ﻗـﺎﭘﻼﺵ ﯞﻩ ﻗـﺎﭘﺘﯩﻦ ﻳﯧـﺸﯩﺶ ﻣﻪﺷـﻐﯘﻻﺗﻰ‬
‫ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﻤﺎﻳﺪﯗ‪.‬‬

‫‪ C#‬ﺩﯨـــﻦ ﺗﺎﺭﺗﯩـــﭗ‪ foreach ،‬ﺟﯜﻣﻠﯩـــﺴﯩﻨﻰ ﺋﯩـــﺸﻠﯩﺘﯩﭗ ﭼـــﺎﺭﻻﺵ ﻣﻪﺷـــﻐﯘﻻﺗﯩﻨﻰ ﺗﯧﺨﯩﻤـــﯘ‬ ‫‪1.x‬‬


‫ﺋﺎﺩﺩﯨﻴﻼﺷﺘﯘﺭﻏﯩﻠﻰ ﺑﻮﻟﺪﻯ‪ .‬ﻛﻮﺩ ‪ 2.10‬ﻧﯩﯔ ﻧﻪﺗﯩﺠﯩﺴﻰ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﯩﺴﺎﻟﻨﯩﯖﻜﻰ ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ‪.‬‬
‫ﻛﻮﺩ ‪2.10‬‬

‫‪public class DemoEnumeration { ‬‬
‫‪    public static void DemoCountdownForeach() { ‬‬
‫‪        Countdown countdown = new Countdown(); ‬‬
‫‪        countdown.StartCountdown = 5; ‬‬
‫‪ ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪20‬‬

‫‪        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‬ﺟﯜﻣﻠﯩــﺴﻰ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﻛــﻮﺩ‪-‬ﺗﻪﺭﺟﯩﻤــﺎﻧﻨﻰ ﺋﺎﭘﺘﻮﻣﺎﺗﯩــﻚ ﮬﺎﻟــﺪﺍ‬


‫‪return‬‬ ‫‪ yield‬ﺟﯜﻣﻠﯩـﺴﯩﻨﻰ ﭘﻪﻗﻪﺕ‬ ‫‪ IEnumerator‬ﺋﯧﻐﯩﺰﯨﻨـﻰ ﮬﺎﺳـﯩﻞ ﻗﯩﻠـﺪﯗﺭﻏﯩﻠﻰ ﺑﻮﻟﯩـﺪﯗ‪.‬‬
‫ﻳــﺎﻛﻰ ‪ 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‬ﺟﯜﻣﻠﯩــﺴﯩﻨﻰ ﺋــﯚﺯ ﺋﯩﭽﯩــﮕﻪ ﺋﺎﻟﻐــﺎﻥ ﻣﯧﺘــﻮﺩ ﺧــﯘﻟﻘﯩﻨﻰ ﮬﻪﻗﯩﻘﯩــﻲ‬
‫ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ ﺑﻮﻟﯩﺪﯗ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪21‬‬

‫‪ 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<int> { ‬‬
‫‪    public int StartCountdown; ‬‬
‫‪ ‬‬
‫‪    IEnumerator IEnumerable.GetEnumerator() { ‬‬
‫‪        return this.GetEnumerator(); ‬‬
‫‪    } ‬‬
‫‪    public IEnumerator<int> GetEnumerator() { ‬‬
‫‪        for (int i = StartCountdown ‐ 1; i >= 0; i‐‐) { ‬‬
‫‪            yield return i; ‬‬
‫‪        } ‬‬
‫‪    } ‬‬
‫‪} ‬‬

‫ﻛﯜﭼﻠﯜﻙ ﺗﯩﭙﻼﻧﻐﺎﻥ ﻧﯘﺳﺨﯩﺴﯩﺪﺍ ﺋﯩﻜﻜﻰ ﺩﺍﻧﻪ ‪ GetEnumerator‬ﻣﯧﺘﻮﺩﻯ ﺋﯧﻨﯩﻘﻼﻧﻐﺎﻥ ﺑﻮﻟـﯘﭖ‪ ،‬ﺑﯩـﺮﻯ‬


‫ﻛﯚﭖ ﻣـﺎﺱ ﺑﻮﻟﻤﯩﻐـﺎﻥ ﻛﻮﺩﻻﺭﻏـﺎ )‪ IEnumerable‬ﻧـﻰ ﻗﺎﻳﺘﯘﺭﯨـﺪﯨﻐﺎﻥ( ﻣـﺎﺱ ﻛﯧﻠﯩـﺪﯗ‪ ،‬ﻳﻪﻧﻪ ﺑﯩـﺮﻯ‬
‫ﺑﻮﻟﺴﺎ ﻛﯜﭼﻠﯜﻙ ﺗﯩﭙﻼﻧﻐﯩﻨﻰ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪22‬‬

‫‪ C# 3.0‬ﻧﯩﯔ ﺧﯘﺳﯘﺳﯩﻴﻪﺗﻠﯩﺮﻯ‬

‫‪ var‬ﺧﺎﺱ ﺳﯚﺯﻯ‬
‫ﻳﯧﯖﯩــﺪﯨﻦ ﻗﻮﺷــﯘﻟﻐﺎﻥ ‪ var‬ﺧــﺎﺱ ﺳــﯚﺯﻯ ﺋــﺎﺭﻗﯩﻠﯩﻖ‪ ،‬ﺗﯩﭙــﻰ ﺋﯧﻨﯩــﻖ ﺑﻮﻟﻤﯩﻐــﺎﻥ ﺋﯚﺯﮔﻪﺭﮔــﯜﭼﻰ ﻣﯩﻘ ـﺪﺍﺭ‬
‫‪.NET‬‬ ‫ﺋﯧﻨﯩﻘﻼﺷــﻘﺎ ﺑﻮﻟﯩــﺪﯗ‪ var .‬ﺑﯩــﻠﻪﻥ ﺑﺎﺷــﻘﺎ »ﺋﯧﻨﯩــﻖ ﺗﯩــﭙﻼﺭ« ﺋﺎﺭﯨــﺴﯩﺪﯨﻜﻰ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺷــﻨﻰ‬
‫ﻗﯘﺭﯗﻟﻤﯩــﺴﻰ ﺋﺎﭘﺘﻮﻣﺎﺗﯩــﻚ ﺑﯧﺠﯩﺮﻩﻟﻪﻳــﺪﯗ‪ .‬ﺷــﯘﻧﻰ ﺋﻪﺳــﻜﻪﺭﺗﯩﺶ ﺯﯙﺭﯛﺭﻛــﻰ‪ 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 ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪23‬‬

‫‪    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‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪24‬‬

‫ﺑﯘ ﺋﯜﭺ ﻗﯘﺭ ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﮬﻪﻣﻤﯩﻤﯩﺰﮔﻪ ﭼﯜﺷﯜﻧﯜﺷﻠﯜﻙ‪ .‬ﻳﯘﻗﯩﺮﯨﻘﻰ ﺟﯜﻣﻠﯩﻠﻪﺭﻧﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻳﻮﻝ ﺋـﺎﺭﻗﯩﻠﯩﻖ‬
‫ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﯩﻠﻰ ﺑﻮﻻﻣﺪﯗ ﺩﻩﭖ ﭘﻪﺭﻩﺯ ﻗﯩﻠﯩﭗ ﺑﺎﻗﺎﻳﻠﻰ‪:‬‬
‫ﻛﻮﺩ ‪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; ‬‬
‫‪        } ‬‬
‫‪    } ‬‬

‫ﺋﻪﻣﺪﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺭﻩﺳﯩﻤﮕﻪ ﻗﺎﺭﺍﯓ‪:‬‬


‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪25‬‬

‫ﺩﯦﻤﻪﻙ‪Increase() ،‬ﺑﯩﻠﻪﻥ )(‪ Decrease‬ﺋﻪﻣﺪﻯ ‪ int‬ﻧﯩﯔ »ﺑﻮﻟﯘﭖ ﻛﻪﺗﺘﻰ«‪.‬‬

‫ﻳﯧــﺰﯨﺶ ﻗﺎﺋﯩﺪﯨــﺴﯩﻨﻰ ﺗﯧﺨﯩﻤــﯘ ﺗﻪﭘــﺴﯩﻠﯩﻴﺮﻩﻙ ﭼﯜﺷــﯜﻧﯜﺵ ﺋﯜﭼــﯜﻥ )(‪ Increase‬ﻣﯧﺘــﻮﺩﯨﻨﻰ ﻣﯩــﺴﺎﻟﻐﺎ‬


‫ﺋﺎﻻﻳﻠﻰ‪ .‬ﻛﯧﯖﻪﻳﺘﯩﺶ ﺋﯘﺳﯘﻟﯩﻨﯩﯔ ﺋﻮﺭﺗﺎﻕ ﻗﯘﺭﯗﻟﻤﯩﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺑﻮﻟﯩﺪﯗ‪:‬‬

‫ﻳﯘﻗﯩﺮﯨﻘﻰ ﻗﯘﺭﯗﻟﻤﯩﺪﯨﻜﻰ ﺋﺎﺳﺘﯩﻐﺎ ﻗﯩﺰﯨﻞ ﺳﯩﺰﯨﻖ ﺳﯩﺰﯨﻠﻐﺎﻧﻠﯩﺮﯨﻨﻰ ﺋﯚﺯ ﭘﯧﺘﻰ ﻳﯧﺰﯨﺸﯩﯖﯩﺰ ﻛﯧﺮﻩﻙ‪ .‬ﻳﯧﺸﯩﻞ‬
‫ﺳﯩﺰﯨﻖ ﺳﯩﺰﯨﻠﻐﺎﻧﻠﯩﺮﻯ ﺑﻮﻟﺴﺎ ﺋﯧﮫﺘﯩﻴﺎﺟﻐﺎ ﻗﺎﺭﺍﭖ ﺋﯚﺯﮔﯜﺭﯨﺪﯗ‪ .‬ﺩﯦﻤﻪﻙ‪:‬‬
‫ﻛﯧﯖﻪﻳـــﺘﯩﺶ ﻣﯧﺘـــﻮﺩﻯ ﯞﻩ ﺋـــﯘﻧﻰ ﺋـــﯚﺯ ﺋﯩﭽﯩـــﮕﻪ ﺋﺎﻟﻐـــﺎﻥ ﺗـــﯜﺭ ﭼﻮﻗـــﯘﻡ ﺗﯘﺭﺍﻗﻠﯩـــﻖ ﺑﻮﻟﯘﺷـــﻰ‬ ‫‪z‬‬
‫ﻛﯧﺮﻩﻙ)‪.(static‬‬
‫ﻛﯧﯖﻪﻳـــﺘﯩﺶ ﻣﯧﺘﻮﺩﯨﻨﯩـــﯔ ﭘـــﺎﺭﺍﻣﯧﺘﯩﺮﻯ ﺋﺎﻟـــﺪﯨﻐﺎ ‪ this‬ﺧـــﺎﺱ ﺳـــﯚﺯﯨﻨﻰ ﻗﻮﺷـــﯘﺵ ﺋـــﺎﺭﻗﯩﻠﯩﻖ‬ ‫‪z‬‬
‫ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪﻛﭽﻰ ﺑﻮﻟﻐـﺎﻥ ﺗﯩﭙﻨـﻰ ﺑﻪﻟﮕﯩﻠﯩـﺸﯩﻤﯩﺰ ﻛﯧـﺮﻩﻙ‪ .‬ﻣﻪﺳـﯩﻠﻪﻥ‪ :‬ﻳﯘﻗـﺎﺭﻗﻰ ﻣﯩـﺴﺎﻟﺪﺍ ‪ int‬ﺗﯩﭙﯩﻨـﻰ‬
‫ﻛﯧﯖﻪﻳﺘﯩﺪﯗ‪.‬‬
‫ﻛﯧﯖﻪﻳﺘﯩﺶ ﻣﯧﺘﻮﺩﯨﻨﯩﯔ ﻗﺎﻳﺘﯘﺭﻣﺎ ﻗﯩﻤﻤﻪﺕ ﺗﯩﭙﻰ ﺧﺎﻟﯩﻐﺎﻧﭽﻪ ﺑﻮﻟﺴﺎ ﺑﻮﻟﯩﺪﯗ‪ .‬ﻣﻪﺳﯩﻠﻪﻥ‪:‬‬ ‫‪z‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪26‬‬

‫ﻛﻮﺩ ‪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 ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪27‬‬

‫ﺋﻪﮔﻪﺭ ﺋﺎﺷﯘﺭﻣﺎﻗﭽﻰ ﺑﻮﻟﻐـﺎﻥ ﻗﯩﻤﻤﻪﺗﻨـﻰ ﭘﺎﺗـﺎﻣﯧﺘﯩﺮ ﺋـﺎﺭﻗﯩﻠﯩﻖ ﻳـﻮﻟﻼﭖ ﺑﻪﺭﺳـﻪﻛﭽﯘ؟ ﺋﻪﻟـﯟﻩﺗﺘﻪ ﺑﻮﻟﯩـﺪﯗ‪.‬‬
‫ﺑﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛﻮﺩ ﻳﺎﺯﯨﻤﯩﺰ‪:‬‬
‫ﻛﻮﺩ ‪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 ‬‬


‫;)'‪string str2 = str1.ExtendedTrim('.‬‬ ‫"ﻛﯩﺮﺩﯨﻢ ﻣﻪﻧﻴﺎﺷﻘﺎ" == ‪// str2‬‬

‫ﻳﯩﻐﯩﻨﭽﺎﻗﻠﯩﻐﺎﻧﺪﺍ ﺗﯜﺭ)ﻳﺎﻛﻰ ﺗﯩﭗ(ﻻﺭ ﺋﺎﺭﯨـﺴﯩﺪﯨﻜﻰ ﻣﯧﺘـﻮﺩ ﻛﯧﯖﻪﻳﺘﯩـﺸﻨﻰ ﺗﯚﯞﻩﻧـﺪﯨﻜﻰ ﻗﯧﻠﯩﭙﻼﺷـﺘﯘﺭﯗﺵ‬


‫ﻣﯘﻣﻜﯩﻦ‪:‬‬
‫ﻛﻮﺩ ‪2.25‬‬

‫‪public class A { ‬‬
‫‪    public virtual void X() {} ‬‬
‫‪} ‬‬
‫‪public class B : A { ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪28‬‬

‫‪    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; ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪29‬‬

‫‪    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‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 30

‫ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ‬:‫ ﻣﻪﺳﯩﻠﻪﻥ‬.‫ﺑﯘ ﻗﺎﺋﯩﺪﻩ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻣﻪﺳﯩﻠﯩﻠﻪﺭﺩﻩ ﺗﯧﺨﯩﻤﯘ ﻛﯜﭼﯩﻨﻰ ﻛﯚﺭﺳﯩﺘﯩﺪﯗ‬


‫ﻣﯘﻧﺎﺳﯩﯟﻩﺗﻠﯩﻚ ﺋﯩﻜﻜﻰ ﺗﯜﺭ ﺑﺎﺭ‬
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 } 
}; 
‫ﻳﺎﻛﻰ‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪31‬‬

‫‪Rectangle r = new Rectangle { ‬‬
‫‪    TL = { X = 0, Y = 1 }, ‬‬
‫‪    BR = { X = 2, Y = 3 } ‬‬
‫‪}; ‬‬

‫ﺋﻪﮔﻪﺭ ﻗﯘﺭﻣﺎﻗﭽﻰ ﺑﻮﻟﻐﯩﻨﯩﯖﯩﺰ ﻣﻪﻟﯘﻡ ﺗﯜﺭﻧﯩﯔ ﺗﯩﺰﯨﻤﻠﯩﻜﻰ ﺑﻮﻟﺴﺎ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻗﺎﺋﯩﺪﻩ ﻳﻪﻧﯩﻼ ﻛﯜﭼﻜﻪ ﺋﯩﮕﻪ‪:‬‬
‫ﻛﻮﺩ ‪2.32‬‬

‫‪List<int> integers = new List<int> { 1, 3, 9, 18 }; ‬‬
‫‪ ‬‬
‫‪List<Customer> list = new List<Customer> { ‬‬
‫‪    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 }; ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪32‬‬

‫ﺑﯘ ﻳﻪﺭﺩﯨﻜﻰ ‪ c1‬ﺑﯩـﻠﻪﻥ ‪ c2‬ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩـﯔ ﺗﯩﭙـﻰ ﺑﻮﻟـﺴﺎ »ﻧـﺎﻣﻠﯩﻖ ﺗﯩـﭗ« ﻳﻪﻧـﻰ ﺋﯘﻻﺭﻧﯩـﯔ ﺗﯩﭙـﻰ‬
‫‪ .Customer‬ﺑﯘ ﺋﯩﻜﻜﯩﺴﯩﻨﯩﯔ ﺋﺎﺭﯨﺴﯩﺪﯨﻜﻰ ‪c2‬ﻧﯩﯔ ﻧﯩﻤﯩﺸﻘﺎ ‪ Customer‬ﺗﯩﭗ ﺑﻮﻟﯘﭖ ﻗﺎﻟﻐﺎﻧﻠﯩﻘﯩـﺪﯨﻜﻰ‬
‫ﺳﻪﯞﻩﺏ ﻛﻮﺩ‪-‬ﺗﻪﺭﺟﯩﻤﺎﻧﻨﯩﯔ)‪ (编译器‬ﺟﯜﻣﻠﯩﻨﯩﯔ ﺑﺎﺵ‪ -‬ﺋﺎﺧﯩﺮﯨﻐـﺎ ﺋﺎﺳﺎﺳـﻪﻥ ﺋﺎﭘﺘﻮﻣﺎﺗﯩـﻚ ﻛﻪﻟﺘـﯜﺭﯛﭖ‬
‫ﭼﯩﻘﺎﺭﻏﺎﻧﻠﯩﻘﯩﺪﺍ‪ c3,c4,c5,c6 .‬ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩﯔ ﺗﯩﭙﻰ ﺑﻮﻟﺴﺎ »ﻧﺎﻣﺴﯩﺰ ﺗﯩﭗ« ﻳﻪﻧﻰ ﺋﯘﻻﺭﻧﯩﯔ ﺗﯩﭗ‬
‫ﻳﻮﻕ‪ Customer) .‬ﻣﯩﻜﯩـﻦ ﺩﻩﭖ ﺋـﻮﻳﻼﭖ ﻗﺎﻟﻤـﺎﯓ(‪ .‬ﺳـﻪﯞﻩﺑﻰ ﺋـﯘﻻﺭ ﺋﻮﺭﯗﻧﻼﺷـﻘﺎﻥ ﻗـﯘﺭﻻﺭﺩﺍ ﺋﯘﻻﺭﻧﯩـﯔ‬
‫‪ Customer‬ﺋﯩﻜﻪﻧﻠﯧﻜﯩﻨﻰ ﺑﯩﻠﮕﯩﻠﻰ ﺑﻮﻟﯩﺪﯨﻐﺎﻥ ﻳﯧﺘﻪﺭﻟﯩﻚ ﺋﺎﺳﺎﺱ ﻳﻮﻕ‪.‬‬
‫ﺋﻪﻣﯩــﺴﻪ ﺑــﯘ ﻧﺎﻣــﺴﯩﺰ ﺗﯩﭙﻠﯩــﻖ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩــﯔ ﺧﺎﺳــﻠﯩﻘﻠﯩﺮﯨﻨﯩﯔ ﺋﯩــﺴﯩﻤﻠﯩﺮﻯ ﻗﺎﻳــﺴﻰ؟ ﺋﯘﻻﺭﻧﯩــﯔ‬
‫ﻗﯩﻤﻤﻪﺗﻠﯩﺮﯨﭽﯘ؟ ﺋﯘﻻﺭﻧﻰ ﻗﺎﻧﺪﺍﻕ ﺯﯨﻴﺎﺭﻩﺕ ﻗﯩﻠﯩﻤﯩﺰ؟‬

‫ﺧﺎﺳــﻠﯩﻖ ﻗﯩﻤﻤﯩﺘﯩﻨﯩــﯔ‬ ‫ﺧﺎﺳـــﻠﯩﻖ ﻧﺎﻣﯩﻨﯩـــﯔ‬


‫ﺧﺎﺳﻠﯩﻖ ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻯ‬ ‫ﺧﺎﺳﻠﯩﻘﻠﯩﺮﻯ‬ ‫ﺋﻮﺑﻴﯧﻜﯩﺖ‬
‫ﻣﻪﻧﺒﻪﺳﻰ‬ ‫ﻛﯧﻠﯩﺶ ﻣﻪﻧﺒﻪﺳﻰ‬

‫ﺋﯚﺯﯨﻤﯩﺰ ﺑﻪﺭﮔﻪﻥ‬ ‫"‪ "Tom‬ﺑﯩﻠﻪﻥ ‪31‬‬ ‫ﺋﯚﺯﯨﻤﯩﺰ ﺑﻪﺭﮔﻪﻥ‬ ‫‪ Name‬ﺑﯩﻠﻪﻥ ‪Age‬‬ ‫‪c3‬‬
‫‪ c2‬ﺩﯨـــــــــــــــﻦ ‪c2‬ﻧﯩـــﯔ ﻣﯘﻧﺎﺳـــﯩﭗ‬ ‫‪ Name‬ﺑﯩﻠﻪﻥ ‪Age‬‬
‫‪c2‬‬ ‫ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻯ ﺑﯩـﻠﻪﻥ‬ ‫ﺗﻪﻗﻠﯩﺪﻟﯩﯟﺍﻟﺪﻯ‬ ‫‪c4‬‬
‫ﺋﻮﺧﺸﺎﺵ‬
‫‪c1‬ﺩﯨـــــــــــــــــــﻦ ‪1c‬ﻧﯩـــﯔ ﻣﯘﻧﺎﺳـــﯩﭗ‬ ‫‪ Name‬ﺑﯩﻠﻪﻥ ‪Contry‬‬
‫‪c1‬‬ ‫ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻯ ﺑﯩـﻠﻪﻥ‬ ‫ﺗﻪﻗﻠﯩﺪﻟﯩﯟﺍﻟﺪﻯ‬ ‫‪c5‬‬
‫ﺋﻮﺧﺸﺎﺵ‬
‫‪c1‬ﺩﯨـــــــــــــــــﻦ ‪c1‬ﻧﯩــﯔ ﻣﯘﻧﺎﺳــﯩﭗ‬ ‫‪ Contry‬ﺑﯩﻠﻪﻥ ‪Name‬‬
‫‪c1‬‬ ‫ﻗﯩﻤﻤﻪﺗﻠﯩـــــــــﺮﻯ‬ ‫ﺗﻪﻗﻠﯩﺪﻟﯩﯟﺍﻟﺪﻯ‬ ‫‪c6‬‬
‫ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ‬

‫ﺋﻪﮔﻪﺭ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﭘﺮﮔﺮﺍﻣﻤﺎ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﯘ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩﯔ ﺗﯩﭙﯩﻨـﻰ ﻛﯚﺭﺳﻪﺗـﺴﻪﻙ ﻧﻪﺗﯩـﺠﻪ ﺋﺎﺳـﺘﯩﺪﯨﻜﻰ‬


‫ﺭﻩﺳﯩﻤﺪﻩ ﻛﯚﺭﺳﯩﺘﯩﻠﮕﻪﻧﺪﻩﻙ ﺑﻮﻟﯩﺪﯗ‪.‬‬
‫‪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() ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪33‬‬

‫ﺩﯦﻤﻪﻙ ﻣﯘﻧﺪﺍﻕ ﻳﻪﻛﯜﻧﮕﻪ ﺋﯧﺮﯨﺸﻪﻟﻪﻳﻤﯩﺰ‪:‬‬

‫ﺑﯘﻻﺭﻧﯩﯔ ﺋﺎﺭﯨﺴﯩﺪﻛﻰ ‪ 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 ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪34‬‬

‫‪    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<T‬ﺋﯧﻐﯩﺰﯨﻨﻰ ﺋﻪﻣﻪﻟـﮕﻪ ﺋﺎﺷـﯘﺭﻏﺎﻥ ﺋـﻮﺑﻴﯧﻜﯩﺘﻨﻰ‬
‫ﺑﻪﻟﮕﯩﻠﻪﻳﺪﯗ‪ .‬ﺑﯘ ﻳﻪﺭﺩﯨﻜﻰ >‪ IEnumerable<T‬ﺋﯧﻐﯩﺰﯨﻨﻰ ﺋﻪﻣﻪﻟـﮕﻪ ﺋﺎﺷـﯘﺭﯗﺵ ﺩﯦﮕﻪﻧﻨـﻰ ﺯﺍﻏـﺮﺍ ﺗﯩـﻞ‬
‫ﺋﯧﻴﺘﻘﺎﻧﺪﺍ ﺋﻪﺯﺍﻟﯩﺮﯨﻨﻰ ﺑﯩـﺮ‪-‬ﺑﯩـﺮﻟﻪﭖ ﺋﻮﻗـﯘﻏﯩﻠﻰ ﺑﻮﻟﯩـﺪﯗ‪ ،‬ﻳﻪﻧـﻰ ‪ foreach‬ﻧـﻰ ﺋﯩﺸﻠﯩﺘﯩـﺸﻜﻪ ﺑﻮﻟﯩـﺪﯗ‬
‫ﺩﯦﮕﻪﻧﻠﯩﻚ‪.‬‬
‫ﻳﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺗﻮﭘﻨﻰ ﺑﺎﺭﻟﯩﻘﻘﺎ ﻛﻪﻟﺘﯜﺭﯨﺪﯗ‬
‫‪{ 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‬‬
‫ﻣﯩﺰﻭﺗﻠﯩﺮﯨﻨﯩﯔ ﺋﻮﺭﻧﯩﻐﺎ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪35‬‬

‫‪ Linq‬ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯧﺴﯩﺪﯨﻦ ﺋﺎﺳﺎﺱ‬ ‫ﺗﯚﺗﯩﻨﭽﻰ ﺑﺎﺏ‬

‫ﺯﺍﻣﺎﻧﯩﯟﻯ ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﺗﯩﻠﻰ ﯞﻩ ﻳﯘﻣﺸﺎﻕ ﺩﯦﺘـﺎﻟﻼﺭ ﺋﺎﺳﺎﺳـﻪﻥ ﺩﯦﮕﯩـﺪﻩﻙ ﺋﻮﺑﻴﯧﻜﯩﺘﻘـﺎ ﻳـﯜﺯﻟﻪﻧﮕﻪﻥ ﻗﯘﺭﯗﻟﻤـﺎ‬
‫ﺗﻪﺭﻩﭘـﺪﺍﺭﻯ ﺑﻮﻟﯘﯞﺍﺗﯩــﺪﯗ‪ .‬ﻧﻪﺗﯩﺠﯩــﺪﻩ ﺑﯩﺰﻧﯩــﯔ ﻛــﯚﭖ ﻗﯩــﺴﯩﻢ ﻣﻪﺷــﻐﯘﻻﺗﻠﯩﺮﯨﻤﯩﺰ ﺟﻪﺩﯞﻩﻝ ﯞﻩ ﺭﯦﻜــﻮﺭﺗﻼﺭ‬
‫ﺑﯩﻠﻪﻥ ﺋﻪﻣﻪﺱ ﺑﻪﻟﻜﻰ ﺋﻮﺑﻴﯧﻜﯩﺖ ﺗﻮﭘﻼﻣﻠﯩﺮﻯ ﯞﻩ ﺋﯘﻻﺭﻧﯩﯔ ﺋﻪﺯﺍﻟﯩﺮﻯ ﺑﯩﻠﻪﻥ ﮬﻪﭘﯩﻠﯩﺸﯩﺶ ﺑﻮﻟﯩﯟﺍﺗﯩـﺪﯗ‪.‬‬
‫ﺷــﯘ ﺳــﻪﯞﻩﺑﻠﯩﻚ ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ ﺗﯩﻠﻠﯩــﺮﻯ ﺋﺎﻣــﺎﻝ ﺑــﺎﺭ ﻣــﯘﻗﯩﻢ ﺳــﺎﻥ ﻣﻪﻧﺒﻪﻟﯩﺮﯨﻨــﻰ)ﻣﻪﺳــﯩﻠﻪﻥ‪ :‬ﺳــﺎﻧﺪﺍﻥ(‬
‫ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﯨــﺪﯨﻦ ﺋــﺎﻳﺮﯨﺶ ﻳــﻮﻟﻠﯩﺮﻯ ﺋﯜﺳــﺘﯩﺪﻩ ﺋﯩﺰﺩﯨﻨﯩﯟﺍﺗﯩــﺪﯗ‪ .‬ﺗﯩﻠﻐــﺎ ﺋﻮﺭﻧﯩﺘﯩﻠﻐــﺎﻥ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ‬
‫)‪ (Language Integrated Query‬ﻳﻪﻧــﻰ ﺋﺎﺗــﺎﻟﻤﯩﺶ ‪ Linq‬ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮﻻﺭﻧــﻰ ﺗﺎﺭﻣــﺎﻗﭽﯩﻼﺭ ﺗﯩﺰﻣﯩــﺴﻰ‬
‫‪،database‬‬ ‫)ﻳﻪﻧــﻰ ﺋــﻮﺑﻴﯧﻜﯩﺘﻼﺭ ‪ ،objects‬ﮔﻪﯞﺩﯨــﻠﻪﺭ ‪ ،entities‬ﺳــﺎﻧﺪﺍﻥ ﺭﯦﻜــﻮﺭﺗﻠﯩﺮﻯ ‪records‬‬
‫‪ XML‬ﻧــﯘﺧﺘﯩﻠﯩﺮﻯ ﻗﺎﺗــﺎﺭﻟﯩﻘﻼﺭ( ﻏــﺎ ﻧﯩــﺴﺒﻪﺗﻪﻥ ﺋﯜﻧﯜﻣﻠــﯜﻙ ﻣﻪﺷــﻐﯘﻻﺕ ﻗﯩﻠﯩــﺶ ﭼﺎﺭﯨــﺴﻰ ﺑﯩــﻠﻪﻥ‬
‫ﺗﻪﻣﯩﻨﻠﻪﻳــﺪﯗ‪ .‬ﺋﯘﻧﯩــﯔ ﺋﻪﯓ ﺋﯘﺗﯘﻗﻠــﯘﻕ ﻳﯧــﺮﻯ ﺷــﯘﻛﻰ ﺋــﯘ ﺗﯩﺰﻣﯩﻼﺭﻏــﺎ )ﺳــﺎﻧﺪﺍﻧﻤﯘ ﺷــﯘ( ﻻﺭﻏــﺎ ﺑﻮﻟﻐــﺎﻥ‬
‫ﻣﻪﺷــﻐﯘﻻﺗﯩﯖﯩﺰﻧﻰ ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ ﺗﯩﻠــﻰ ﺑﯩــﻠﻪﻥ ﻳﯜﻛــﺴﻪﻙ ﺩﻩﺭﯨﺠﯩــﺪﻩ ﻳﯧﻘﯩﻨﻼﺷــﺘﯘﺭﻏﺎﻥ ﺑﻮﻟــﯘﭖ ﭘﺮﻭﮔﺮﺍﻣﻤــﺎ‬
‫ﺗﯩﻠﯩﻨﯩﯔ ﺋﺎﺩﺩﻯ ﻗﺎﺋﯩﺪﯨﻠﯩﺮﻯ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻣﯘﺭﻩﻛﻜﻪﭖ ﻣﻪﺷﻐﯘﻻﺗﻼﺭﻧﻰ)ﻣﻪﺳﯩﻠﻪﻥ ﺳـﺎﻧﺪﺍﻥ ﻣﻪﺷـﻐﯘﻻﺗﻠﯩﺮﻯ(‬
‫ﺋﯩﻠﯩﭗ ﺑﺎﺭﺍﻻﻳﺴﯩﺰ‪.‬‬

‫‪ LINQ‬ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻠﯩﺮﻯ )‪(LINQ Queries‬‬


‫‪ LINQ‬ﺑﯩـــﺮ ﻗﯩـــﺴﯩﻢ ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﺋﻪﻣﻪﻟﻠﯩﺮﯨﻨـــﻰ ﺋﺎﺳـــﺎﺱ ﻗﯩﻠﯩـــﺪﯨﻐﺎﻥ ﺑﻮﻟـــﯘﭖ‪ ،‬ﺋﺎﺳﺎﺳـــﻠﯩﻘﻰ‬
‫>‪ IEnumerable<T‬ﺋﯧﻐﯩﺰﯨﻨــﻰ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﻏﺎﻥ ﮬﻪﺭﻗﺎﻧــﺪﺍﻕ ﺗﯩﭙﻘــﺎ ﻣﻪﺷــﻐﯘﻻﭖ ﺋﯧﻠﯩــﭗ ﺑﺎﺭﺍﻻﻳــﺪﯗ‪.‬‬
‫ﺋﯘﻧﯩﯔ ﺋﯜﺳﺘﯩﮕﻪ ‪.Net‬ﻗﯘﺭﯗﻟﻤﯩﺴﯩﺪﯨﻜﻰ ﻣﯘﺗﻠﻪﻕ ﻛﯚﭖ ﻗﯩﺴﯩﻢ ﺗﻮﭘﻼﻡ ﺗﯩﭙﻠﯩﺮﻯ ﻣﻪﺯﻛﯘﺭ ﺋﯧﻐﯩﺰﻧﻰ ﺋﻪﻣﻪﻟﮕﻪ‬
‫ﺋﺎﺷﯘﺭﻏﺎﻥ‪ .‬ﮬﻪﺗﺘﺎ ﺋﯘﻧﻰ ﺋﯚﺯﯨﯖﯩﺰﻧﯩﯔ ﺗﯩﭙﻠﯩﺮﯨـﺪﺍ ﺋﻪﻣﻪﻟـﮕﻪ ﺋﺎﺷـﯘﺭﻣﺎﻗﻤﯘ ﻗﯧـﻴﯩﻦ ﺋﻪﻣﻪﺱ‪ .‬ﺩﯦـﻤﻪﻙ ‪Linq‬‬
‫ﭘﺮﻭﮔﺮﺍﻣﻤﯩﯖﯩﺰﻧﯩﯔ ﻛﯚﭖ ﻗﯩﺴﯩﻢ ﺑﯚﻟﻪﻛﻠﯩﺮﯨﺪﻩ ﻧﺎﻣﺎﻳﻪﻥ ﺑﻮﻻﻻﻳﺪﯗ‪.‬‬

‫‪ Linq‬ﺑﻪﻟﮕﯩﻠﯩــﻚ ﻛﯧﯖﻪﻳﺘﯩــﺸﭽﺎﻧﻠﯩﻘﻘﺎ ﺋﯩــﮕﻪ ﺑﻮﻟــﯘﭖ‪ ،‬ﺋﻮﺧــﺸﯩﻤﯩﻐﺎﻥ ﺗــﯜﺭﺩﯨﻜﻰ ﺳــﺎﻥ ﻣﻪﺷــﻐﯘﻻﺗﻠﯩﺮﯨﻐﺎ‬


‫ﺧﺎﺳﻼﺷﺘﯘﺭﻏﯩﻠﻰ ﺑﻮﻟﯩﺪﯗ‪ .‬ﻣﻪﺳﯩﻠﻪﻥ ‪ Linq To Sql‬ﺋﺎﺭﻗﯩﻠﯩﻖ ‪ MsSQL‬ﺳﺎﻧﺪﺍﻧﯩﻐﺎ ‪Linq To XML ،‬‬
‫ﺋﺎﺭﻟﯩﻖ ‪ XML‬ﺋﯘﭼﯘﺭﻟﯩﺮﯨﻐﺎ ﺋﯜﻧﯜﻣﻠﯜﻙ ﻣﻪﺷﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﯩﺪﯗ‪.‬‬

‫ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﺴﻰ‬
‫ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﻨﻰ ﺳﯚﺯﻟﻪﺷﺘﯩﻦ ﺑﯘﺭﯗﻥ ﮔﻪﭘﻨﻰ ﺋﺎﺩﺩﻯ ﻣﯩﺴﺎﻝ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﺎﺷﻼﻱ‪ .‬ﺗﯚﯞﻩﻧﺪﯨﻜﻪﻥ ﺗﯜﺭ ﺑﺎﺭ ﺩﻩﭖ‬
‫ﭘﻪﺭﻩﺯ ﻗﯩﻼﻳﻠﻰ‬
‫{‪public class Developer ‬‬ ‫ﭘﺮﻭﮔﺮﺍﻣﻤﯩﺮ ﺗﯜﺭﻯ‪//‬‬
‫‪    public string Name; ‬‬
‫‪    public string Language; ‬‬
‫‪    public int Age; ‬‬
‫}‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪36‬‬

‫ﻳﯘﻗﺎﺭﻗﻰ ﺗﯜﺭ ﺗﯩﭙﯩﻨﯩﯔ ﺗﻮﭘﻠﯩﻤﯩﻐﺎ ﻣﻪﺷﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﺎﺭﻣﺎﻗﭽﻰ ﺑﻮﻟﯘﯓ‪ 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#‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪37‬‬

‫ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ ﻛﻮﺩ‪-‬ﺗﻪﺭﺟﯩـﻤﻪ ﻗﯩﻠﯩـﺶ ﻣﻪﺯﮔﯩﻠﯩـﺪﻩ ‪ where‬ﺋﯩﭙﺎﺩﯨـﺴﻰ ‪ System.Linq‬ﻧـﺎﻡ ﺑﻮﺷـﻠﯩﻘﯩﺪﺍ‬


‫ﺋﯧﻨﯩﻘﻼﻧﻐﺎﻥ ‪ Enumerable‬ﺗﯜﺭﯨﻨﯩﯔ ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩﻯ ‪ Where‬ﻏﺎ ﺋﯚﺯﻟﻪﺷﺘﯜﺭﯛﻟﯩﺪﯗ‪.‬‬
‫‪ System.Linq‬ﻧـــﺎﻡ ﺑﻮﺷـــﻠﯩﻘﯩﺪﺍ >‪ IEnumerable<T‬ﺋﯜﭼـــﯜﻥ ﻧﯘﺭﻏﯘﻧﻠﯩﻐـــﺎﻥ ﻛﯧﯖﻪﻳـــﺘﻤﻪ ﻣﯧﺘـــﻮﺩﻻﺭ‬
‫ﺗﻪﻣﯩﻨﻠﻪﻧﮕﻪﻥ‪.‬‬
‫ﺩﯦﻤﻪﻙ ﻳﯘﻗﺎﺭﺩﯨﻜﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﻣـﺎﮬﯩﻴﻪﺗﺘﻪ ﺗﯚﯞﻩﻧـﺪﯨﻜﻰ ﺋﺎﺳﺎﺳـﻰ ﻣﯧﺘـﻮﺩ ﻗﻮﻟﻠﯩﻨﯩـﺸﯩﻨﯩﯔ‬
‫ﺑﺎﺷﻘﯩﭽﻪ ﺋﯩﭙﺎﺩﯨﻠﯩﻨﯩﺸﻰ ﺧﺎﻻﺱ‪.‬‬
‫‪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<Developer,  bool>  filteringPredicate  =  d  =>  d.Language  == ‬‬


‫‪"C#"; ‬‬
‫‪Func<Developer, string> selectionPredicate = d => d.Name; ‬‬
‫‪IEnumerable<string> expr = ‬‬
‫‪    developers ‬‬
‫‪    .Where(filteringPredicate) ‬‬
‫‪    .Select(selectionPredicate); ‬‬

‫‪ C#3.0‬ﻛﻮﺩ‪-‬ﺗﻪﺭﺟﯩﻤﺎﻧﻰ ﻳﯘﻗﯩﺮﯨﻘﻰ ﮬﺎﻟﻪﺗﻜﻪ ﻗﺎﻧﺪﺍﻕ ﻛﻪﻟﺘﯜﺭﯛﺷﻨﻰ ﺑﯩﻠﯩﺪﯗ‪ .‬ﺋﻪﻟﯟﻩﺗﺘﻪ ﺋﻪﮔﻪﺭ ﺳﯩﺰ ‪Linq‬‬
‫ﺑﯩﻠﯩﻤﻠﯩﺮﯨﻨﻰ ﭘﯩﺸﺸﯩﻖ ﺑﯩﻠﯩﭗ ﺑﻮﻟﻐﺎﻧﺪﯨﻦ ﻛﯧﻴﯩﻦ ﺑﯩﯟﺍﺳﺘﻪ ﻣﯘﺷﯘ ﺧﯩﻞ ﮔﯩﺮﺍﻣﺎﺗﯩﻜﯩﻨﻰ ﻗﻮﻟﻼﻧﺴﯩﯖﯩﺰﻣﯘ‬
‫ﺑﻮﻟﯩﺪﯗ‪ .‬ﻟﯧﻜﯩﻦ ﺗﻪﺷﻪﺑﺒﯘﺳﯘﻡ ﺷﯘﻛﻰ ﺯﯙﺭﯛﺭﯨﻴﻪﺕ ﺗﯘﻏﯘﻟﻤﯩﺴﯩﻼ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﯔ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪38‬‬

‫ﺗﻮﻟﯘﻕ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ‬


‫ﺋﺎﻟــﺪﯨﻨﻘﻰ ﻣﻪﺯﻣــﯘﻧﻼﺭﺩﺍ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨــﺴﯩﻨﯩﯔ ﺋــﻮﺑﻴﯧﻜﯩﺘﻼﺭ ﺗــﻮﭘﻠﯩﻤﻰ ﺋﯜﺳــﺘﯩﺪﯨﻜﻰ ﺋــﺎﺩﺩﯨﻲ‬
‫ﻣﻪﺷــﻐﯘﻻﺗﻠﯩﺮﯨﻨﻰ ﻛــﯚﺭﯛﭖ ﺋﯚﺗﺘــﯘﻕ‪ .‬ﺗﻮﻟــﯘﻕ ﺑﻮﻟﻐــﺎﻥ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨــﺴﻰ ﺗﯧﺨﯩﻤــﯘ ﻣــﯘﻛﻪﻣﻤﻪﻝ‬
‫ﮔﺮﺍﻣﻤﺎﺗﯩﻜﯩﻠﯩﻖ ﻗﯘﺭﯗﻟﻤﯩﻐﺎ ﺋﯩـﮕﻪ‪ .‬ﮬﻪﺭﺑﯩـﺮ ﺋﯩﭙـﺎﺩﻩ ‪ 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 39

‫ﻣﯩﺴﺎﻟﻼﺭ ﺋﯜﭼﯜﻥ ﺗﯜﺭ ﻗﯘﺭﯗﻟﻤﯩﺴﻰ‬

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 = 
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 40

  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
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪41‬‬

‫ﻛﻮﺩ ‪4.3‬‬

‫‪var expr = ‬‬
‫‪    from   c in customers ‬‬
‫‪    where  c.Country == Countries.Italy ‬‬
‫‪    select new { c.Name, c.City }; ‬‬

‫ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ ‪ Where‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ‪:‬‬


‫‪public static IEnumerable<T> Where<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, bool> predicate); ‬‬
‫‪public static IEnumerable<T> Where<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫;)‪    Func<T, int, bool> 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‬ﻣﻪﺳـﯩﻠﻪﻥ‪:‬‬
‫ﺳﺎﻧﺪﺍﻥ( ﺩﯨﻦ ﻛﯚﭖ ﻣﯩﻘﺪﺍﺭﺩﯨﻜﻰ ﺋﯘﭼﯘﺭﻧﻰ ﺋﯩﭽﻜﻰ ﺳﺎﻗﻠﯩﻐﯘﭼﻘﺎ ﺋﻮﻗﯘﭖ ﻛﯩﺮﯨـﺸﻨﻰ ﻳﺎﺧـﺸﻰ ﻣﻪﺷـﻐﯘﻻﺕ‬
‫ﺩﯦﮕﯩﻠﻰ ﺑﻮﻟﻤﺎﻳﺪﯗ‪ .‬ﺋﺎﺩﻩﺗﺘﻪ‪ ،‬ﺋﯘﭼﯘﺭﻻﺭﻧﻰ ﺗﯘﺭﻏﯘﻥ ﻗﻪﯞﻩﺕ ﺩﻩﺭﯨﺠﯩﺴﯩﺪﯨﻼ ﺑﻪﺗﻠﻪﺭﮔﻪ ﺑـﯚﻟﮕﻪﻥ)ﺷـﻪﺭﺗﻠﻪﺭ‬
‫ﺋﺎﺭﻗﯩﻠﯩﻖ( ﻳﺎﺧﺸﻰ‪ .‬ﮔﻪﺭﭼﻪ ﺑﯘ ﺧﯩﻞ ﺋﯘﺳﯘﻝ ﺑﺎﺭﻟﯩﻖ ﺋﯘﭼﯘﺭﻧﻰ ﺋﯩﭽﻜـﻰ ﺳـﺎﻗﻠﯩﻐﯘﭼﺘﺎ ﺗـﯘﺭﯗﭖ ﺑﻪﺗـﻠﻪﺭﮔﻪ‬
‫ﺑﯚﻟﮕﻪﻧﮕﻪ ﻗﺎﺭﯨﻐﺎﻥ ﺋﺎﺳﺘﯩﺮﺍﻕ)ﻧﯩﺴﭙﻰ( ﺑﻮﻟﺴﯩﻤﯘ‪ ،‬ﻳﻪﻧﯩﻼ ﭼﻮﻗﯘﻡ ﻛﯩﺮﯨﺶ ﺟﻪﺭﻳﺎﻧﯩﻐﺎ ﻛﻪﺗـﻜﻪﻥ ﯞﺍﻗﯩﺘـﺘﯩﻦ‬
‫ﺋﯘﺗﺎﻻﻳﻤﯩﺰ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪42‬‬

‫ﺋﻪﻣﻪﻟﯩﻠﻪﺷﺘﯜﺭﯛﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )‪(Projection Operators‬‬

‫‪ Select‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ‬
‫ﺋﻪﻣﻪﻟﯩﻠﻪﺷــﺘﯜﺭﯛﺵ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﻣﻪﻧــﺒﻪﺩﯨﻦ ﺋﯘﭼــﯘﺭﻻﺭﻧﻰ ﺷــﻪﺭﺗﻜﻪ ﺋﺎﺳﺎﺳــﻪﻥ ﻳﯩﻐﯩــﭗ ﻧﻪﺗﯩﺠﯩــﮕﻪ‬
‫ﺋﻮﺭﯗﻧﻼﺷﺘﯘﺭﯗﺵ ﺭﻭﻟﯩﻨﻰ ﺋﻮﻳﻨﺎﻳﺪﯗ‪ .‬ﻳﯘﻗﯩﺮﯨﺪﺍ ﻛﯚﭖ ﺋﯘﭼﺮﺍﺗﻘﺎﻥ ‪ Select‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺋﯘﻧﯩﯔ ﺗﯩﭙﯩﻚ‬
‫ﻣﯩــﺴﺎﻟﻰ‪ .‬ﺑﯘﻧــﺪﺍﻕ ﺩﯦﻴﯩــﺸﯩﻤﯩﺰﯨﺪﯨﻜﻰ ﺳــﻪﯞﻩﺏ ﺋــﯘ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﻧﻪﺗﯩﺠﯩــﺴﯩﻨﻰ >‪IEnumerable<T‬‬
‫ﺋﯧﻐﯩﺰﯨﻨﻰ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ ﺋﻮﺑﻴﯧﻜﯩﺖ ﮬﺎﻟﯩﺘﯩﺪﻩ ﻗﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﻩﻟﻪﻳﺪﯗ‪.‬‬
‫‪ Select‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻨﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﯩﺪﻩﻙ‪:‬‬
‫‪public static IEnumerable<S> Select<T, S>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, S> selector); ‬‬
‫‪public static IEnumerable<S> Select<T, S>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫;)‪    Func<T, int, S> selector‬‬

‫ﺧﯘﺩﺩﻯ ‪ 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‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﯩﻨﯩﯔ ﺋﯩﻜﻜﯩﭽـــﻰ ﺧﯩـــﻞ ﺋﻪﻧﺪﯨﺰﯨﯩـــﺴﯩﺪﻩ ﭘﯜﺗـــﯜﻥ ﺳـــﺎﻥ ﺗﯩﭙﻠﯩـــﻖ ﭘـــﺎﺭﺍﻣﯧﺘﺮﻯ‬


‫ﺋﯩﺸﻠﯩﺘﻪﻟﻪﻳﻤﯩﺰ‪ .‬ﺑﯘ ﭘـﺎﺭﺍﻣﯧﺘﯩﺮ ﻣﻪﻧـﺒﻪ ﺋﻮﺑﻴﯧﻜﯩـﺖ ﺗﯩﺰﻣﯩـﺴﯩﺪﯨﻜﻰ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩـﯔ ﻧﯚﻟـﺪﯨﻦ ﺑﺎﺷـﻼﻧﻐﺎﻥ‬
‫ﺗﻪﺭﺗﯩﭗ ﻧﻮﻣﯘﺭﯨﻨﻰ ﻛﯚﺭﺳﯩﺘﯩﺪﯗ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪43‬‬

‫‪ 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<Order‬ﺗﯩﭙﻠﯩـــﻖ ﺑﻮﻟـــﯘﭖ ﻧﻪﺗﯩـــﺠﻪ ﺗﯩﺰﻣﯩـــﺴﯩﻨﯩﯔ ﮬﻪﺭﺑﯩـــﺮ ﺋﻪﺯﺍﺳـــﯩﻤﯘ ﮬﻪﻡ ﻣﻪﻟـــﯘﻡ‬
‫ﺧﯧﺮﯨﺪﺍﺭﻧﯩﯔ ﺯﺍﻛﺎﺯ ﺗﯩﺰﻣﯩﺴﻰ ﺑﻮﻟﯩﺪﯗ)][‪.(Orders‬‬
‫ﭘﺮﻭﮔﺮﺍﻣﻤﯩﻨﯩﯔ ﺋﯩﺠﺮﺍ ﻧﻪﺗﯩﺠﯩﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫][‪DevLeap.Linq.Operators.Order‬‬
‫][‪DevLeap.Linq.Operators.Order‬‬

‫ﺩﯦﻤﻪﻙ ﺑﯘ ﺑﯩﺰ ﻣﻪﻗﺴﻪﺕ ﻗﯩﻠﻐﺎﻥ >‪ IEnumerable<Order‬ﮔﻪ ﺋﯧﺮﯨﺸﯩﺸﻨﯩﯔ ﻧﻪﺗﯩﺠﯩﺴﻰ ﺋﻪﻣﻪﺱ‪.‬‬


‫ﺗﻪﻛﺸﻰ >‪ IEnumerable<Order‬ﺗﯩﭙﻠﯩﻖ ﻧﻪﺗﯩﺠﯩﮕﻪ ﺋﯧﺮﯨـﺸﯩﺶ ﺋﯜﭼـﯜﻥ‪ SelectMany ،‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩـﺴﯩﻨﻰ‬
‫ﺋﯩﺸﻠﯩﺘﯩﺸﻜﻪ ﺗﻮﻏﺮﺍ ﻛﯧﻠﯩﺪﯗ‪ .‬ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫‪public static IEnumerable<S> SelectMany<T, S>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, IEnumerable<S>> selector); ‬‬
‫‪public static IEnumerable<S> SelectMany<T, S>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, int, IEnumerable<S>> selector); ‬‬
‫‪public static IEnumerable<S> SelectMany<T, C, S>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, IEnumerable<C>> collectionSelector, ‬‬
‫‪    Func<T, C, S> resultSelector); ‬‬

‫ﻣﻪﺯﻛﯘﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﭼﺎﺭﻻﭖ ﻧﻪﺗﯩﺠﻪ ﺋﻪﺯﺍﻟﯧﺮﯨﻨﻰ)‪ (items‬ﺑﯩﺮﻟﻪﺷﺘﯜﺭﯨﺪﯗ ﯞﻩ ﺋـﯘﻻﺭﻧﻰ‬


‫ﭼﺎﺭﻻﺷﻘﺎ ﺑﻮﻟﯩـﺪﯨﻐﺎﻥ)>‪IEnumerable<T‬ﻧـﻰ ﺋﻪﻣﻪﻟـﮕﻪ ﺋﺎﺷـﯘﺭﻏﺎﻥ( ﺑﯩـﺮ ﺩﺍﻧﻪ ﺗﯩﺰﻣـﺎ ﺷـﻪﻛﻠﯩﺪﻩ ﻗـﺎﻳﺘﯘﺭﯗﭖ‬
‫ﺑﯧﺮﻩﻟﻪﻳﺪﯗ‪ .‬ﺋﯘﻧﯩﻤﯘ ﺋﯩﻜﻜﯩﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﻰ ﻣﻪﺷﻐﯘﻻﺗﻨﻰ ﺗﻪﺭﺗﯩﭗ ﻧﻮﻣﯘﺭﻯ ﺑﯩﻠﻪﻥ ﺑﺎﻏﻠﯩﻴﺎﻻﻳﺪﯗ‪.‬‬
‫ﺑﺎﻳﯩﻘﻰ ﻣﻪﺳﯩﻠﯩﻨﻰ ‪ SelectMany‬ﺑﯩﻠﻪﻥ ﮬﻪﻝ ﻗﯩﻠﯩﺶ ﭼﺎﺭﯨﺴﻰ ﻣﯘﻧﺪﺍﻕ‪:‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪44‬‬

‫ﻛﻮﺩ ‪4.7‬‬

‫‪IEnumerable<Order> orders = ‬‬
‫‪    customers ‬‬
‫‪    .Where(c => c.Country == Countries.Italy) ‬‬
‫‪    .SelectMany(c => c.Orders); ‬‬

‫ﻛﻮﺩ ‪ 4.7‬ﺩﯨﻜﻰ ﺋﯩﭙﺎﺩﻩ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﺑﯩﻠﻪﻥ ﺑﺎﺭﺍﯞﻩﺭ‪:‬‬


‫ﻛﻮﺩ ‪4.8‬‬

‫‪IEnumerable<Order> 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<Order> orders = ‬‬
‫‪    from   c in customers ‬‬
‫‪    where  c.Country == Countries.Italy ‬‬
‫‪        from   o in c.Orders ‬‬
‫‪        select new {o.Quantity, o.IdProduct}; ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪45‬‬

‫‪ 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<T> OrderBy<T, K>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector); ‬‬
‫‪public static IOrderedSequence<T> OrderBy<T, K>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector, ‬‬
‫‪    IComparer<K> comparer); ‬‬
‫‪public static IOrderedSequence<T> OrderByDescending<T, K>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector); ‬‬
‫‪public static IOrderedSequence<T> OrderByDescending<T, K>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector, ‬‬
‫‪    IComparer<K> comparer); ‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 46

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<T> ThenBy<T, K>( 
    this IOrderedSequence<T> source, 
    Func<T, K> keySelector); 
public static IOrderedSequence<T> ThenBy<T, K>( 
    this IOrderedSequence<T> source, 
    Func<T, K> keySelector, 
    IComparer<K> comparer); 
public static IOrderedSequence<T> ThenByDescending<T, K>( 
    this IOrderedSequence<T> source, 
    Func<T, K> keySelector); 
public static IOrderedSequence<T> ThenByDescending<T, K>( 
    this IOrderedSequence<T> source, 
    Func<T, K> keySelector, 
    IComparer<K> comparer);

‫ ﻣﻪﺷـــــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻧﯩﯖﻜﯩﮕﻪ‬OrderByDescending ‫ ﺑﯩـــــﻠﻪﻥ‬OrderBy ‫ﺋﯘﻻﺭﻧﯩـــــﯔ ﺋﻪﻧـــــﺪﯨﺰﯨﻠﯩﺮﻯ‬


‫ ﻧـﻰ ﭘﻪﻗﻪﺕ‬ThenByDescending ‫ ﺑﯩـﻠﻪﻥ‬ThenBy ،‫ ﭘﻪﺭﻗﻠﯩـﻖ ﻳﯧـﺮﻯ ﺷـﯘﻛﻰ‬.‫ﺋﻮﺧﺸﯩﺸﯩﭗ ﻛﯧﺘﯩـﺪﯗ‬
‫ ﺷـﯘﯕﺎ ﺑـﯘ‬.( ‫ ﻏـﺎ ﺑﻮﻟﻤﺎﻳـﺪﯗ‬IEnumerable<T> ) ‫ ﮔﯩﻼ ﻗﻮﻟﻠﯩﻨﯩﺸﻘﺎ ﺑﻮﻟﯩﺪﯗ‬IOrderedSequence<T>
‫ ﻧﯩــﯔ ﻛﻪﻳﻨــﻰ ﺋــﯘﻻﭘﻼ ﺋﯩــﺸﻠﻪﺗﻜﯩﻠﻰ‬OrderByDescending ‫ ﺑﯩــﻠﻪﻥ‬OrderBy ‫ﺋﯩﻜﻜﯩــﺴﯩﻨﻰ ﭘﻪﻗﻪﺕ‬
‫ ﻻﺭﺩﯨـــﻦ ﻛﻪﻟـــﮕﻪﻥ ﻧﻪﺗﯩـــﺠﻪ‬OrderBy ‫ ﭼـــﯜﻧﻜﻰ‬.‫ ﻣﯘﺳـــﺘﻪﻗﯩﻞ ﺋﯩﺸﻠﯩﺸﺘـــﺸﻜﻪ ﺑﻮﻟﻤﺎﻳـــﺪﯗ‬،‫ﺑﻮﻟﯩـــﺪﯗ‬
.‫ ﻧﻰ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ‬IOrderedSequence<T>
:‫ﺗﯚﯞﻩﻧﺪﻩ ﺑﯘﻧﯩﯖﻐﺎ ﺑﯩﺮ ﻣﯩﺴﺎﻝ ﻛﻪﻟﺴﯘﻥ‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪47‬‬

‫ﻛﻮﺩ ‪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<Order> orders = ‬‬
‫‪    customers ‬‬
‫‪    .SelectMany(c => c.Orders) ‬‬
‫‪    .OrderBy(o => o.Month, new MonthComparer()); ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪48‬‬

‫‪ Reverce‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ )ﻛﯚﻣﺘﯜﺭﯛﺵ(‬
‫ﺑﻪﺯﯨﺪﻩ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩﺴﯩﻨﯩﻨﯩﯔ ﺗﻪﺭﺗﯩﭙﯩﻨﻰ ﺋﻪﻛﺴﯩﮕﻪ ﺋﯚﺭﯛﺵ ﺋﯧﮫﺘﯩﻴـﺎﺟﻰ ﺗﯘﻏﯘﻟﯩـﺪﯗ‪ Linq .‬ﺩﺍ ﺑﯘﻧـﺪﺍﻕ‬
‫ﺋﻪﮬﯟﺍﻟﻐﺎ ﻧﯩﺴﺒﻪﺗﻪﻥ ‪ Reverce‬ﻧﺎﻣﻠﯩﻖ ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ ﺗﻪﻣﯩﻨﻠﻪﻧﮕﻪﻥ‪ .‬ﻳﻪﻧﻰ‪:‬‬
‫‪public static IEnumerable<T> Reverse<T>( ‬‬
‫‪    this IEnumerable<T> 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‬ﻧـــﻰ‬
‫ﺗﻪﻣﯩﻨﻠﯩﮕﻪﻥ‪ .‬ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪49‬‬

‫‪public static IEnumerable<IGrouping<K, T>> GroupBy<T, K>( ‬‬
‫‪    this IEnumerable<T> source, Func<T, K> keySelector); ‬‬
‫‪public static IEnumerable<IGrouping<K, T>> GroupBy<T, K>( ‬‬
‫‪    this IEnumerable<T> source, Func<T, K> keySelector, ‬‬
‫‪    IEqualityComparer<K> comparer); ‬‬
‫‪public static IEnumerable<IGrouping<K, E>> GroupBy<T, K, E>( ‬‬
‫‪    this IEnumerable<T> source, Func<T, K> keySelector, ‬‬
‫‪    Func<T, E> elementSelector); ‬‬
‫‪public static IEnumerable<IGrouping<K, E>> GroupBy<T, K, E>( ‬‬
‫‪    this IEnumerable<T> source, Func<T, K> keySelector, ‬‬
‫‪    Func<T, E> elementSelector, IEqualityComparer<K> comparer); ‬‬

‫ﺑـﺎﺭﻟﯩﻖ ﺋﻪﻧـﺪﯨﺰﯨﻠﯩﺮﻯ >>‪ IEnumerable<IGrouping<K, T‬ﻟﯩـﻖ ﻗﯩﻤـﻤﻪﺕ ﻗﺎﻳﺘﯘﺭﯗﺩﯨﻐـﺎﻥ ﺑﻮﻟـﯘﭖ‪،‬‬


‫ﺑﯘﻧﯩﯖﺪﯨﻜﻰ >‪ IGrouping<K, T‬ﺑﻮﻟﺴﺎ >‪ Enumerable<T‬ﻧﻰ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ ﺧﺎﺳﻼﺷـﺘﯘﺭﯗﻟﻐﺎﻥ‬
‫ﻛﯚﭘﻤﺎﺱ ﺋﯧﻐﯩﺰ‪.‬‬
‫ﻣﻪﺳﯩﻠﻪﻥ‪ GroupBy :‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﻰ ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜـﻰ ﺑـﻮﻳﯩﭽﻪ ﮔﯘﺭﭘﯩﻼﺭﻏـﺎ‬
‫ﺑﯚﻟﯜﺵ ﯞﻩ ﻧﻪﺗﯩﺠﯩﻨﻰ ﺯﯨﻴﺎﺭﻩﺕ ﻗﯩﻠﯩﺶ ﺋﯜﭼﯜﻥ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﻛﻮﺩ ﻳﺎﺯﯨﻤﯩﺰ‪:‬‬
‫ﻛﻮﺩ ‪4.16‬‬

‫‪var expr = customers.GroupBy(c => c.Country); ‬‬
‫‪ ‬‬
‫‪foreach(IGrouping<Countries, Customer> customerGroup in expr) { ‬‬
‫‪    Console.WriteLine("Country: {0}", customerGroup.Key); ‬‬
‫‪    foreach(var item in customerGroup) { ‬‬
‫‪        Console.WriteLine(item); ‬‬
‫‪    } ‬‬
‫‪} ‬‬

‫ﻛﻮﺩ ‪ 4.16‬ﺩﻩ ﻛﯚﺭﺳﯩﺘﯩﻠﮕﻪﻧﺪﻩﻙ ﮬﻪﺭﺑﯩﺮ ﮔﯘﺭﭘﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﻰ)ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ ﺋﻮﺧﺸﺎﺵ ﺑﻮﻟﻐـﺎﻥ‬


‫ﺧﯧﺮﯨﺪﺍﺭﻻﺭ( ﭼﺎﺭﻻﺷﺘﯩﻦ ﺋـﺎﯞﺍﻝ ﭼﻮﻗـﯘﻡ ﮔﻮﺭﯗﭘﯩﻼﺭﻧﯩـﯔ ﺋـﺎﭼﻘﯘﭺ ﺳـﯚﺯﯨﻨﻰ ﭼـﺎﺭﻻﺵ ﻛﯧـﺮﻩﻙ‪ .‬ﮬﻪﺭ ﺑﯩـﺮ‬
‫ﮔﯘﺭﭘــﺎ >‪ IGrouping<Countries, Customer‬ﻟﯩــﻖ ﺋﻮﺑﻴﯧﻜﯩــﺖ‪ .‬ﺑﺎﺷــﻘﯩﭽﻪ ﺋﯧﻴﺘﻘﺎﻧــﺪﺍ‪ ،‬ﻳــﯘﻗﯩﺮﯨﻘﻰ‬
‫ﻣﯩــﺴﺎﻟﻐﺎ ﻧﯩــﺴﺒﻪﺗﻪﻥ‪ ،‬ﺧﯧﺮﯨــﺪﺍﺭﻻﺭ ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﯩــﮕﻪ ﺋﺎﺳﺎﺳــﻪﻥ ﮔﯘﺭﭘﯩﻼﺭﻏــﺎ ﺑﯚﻟﯩﻨﯩــﺪﯗ‪ ،‬ﮬﻪﺭﺑﯩــﺮ‬
‫ﮔﯘﺭﭘﯩﻨﯩﯔ ﺑﯩـﺮ ﺋـﺎﭼﻘﯘﭼﻠﯘﻕ ﺳـﯚﺯﻯ ﺑﻮﻟﯩـﺪﯗ‪ ،‬ﺑـﯘ ﺋـﺎﭼﻘﯘﭼﻠﯘﻕ ﺳـﯚﺯ ﺩﻩﻝ ﺷـﯘ ﮔﯘﺭﭘﯩـﺪﯨﻜﻰ ﺧﯧﺮﯨـﺪﺍﺭ‬
‫ﺋﻮﺭﺗﺎﻕ ﺗﻪﯞﻩ ﺑﻮﻟﻐﺎﻥ ﺩﯙﻟﻪﺕ ﺋﯩﺴﯩﻤﯩﺪﯗﺭ‪.‬‬
‫ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨـــﺴﯩﺪﻩ ‪ goup...by...‬ﺧـــﺎﺱ ﺳـــﯚﺯﻟﯜﻙ ﮔﯩﺮﺍﻣﺎﺗﯩﻜـــﺎ ﺋـــﺎﺭﻗﯩﻠﯩﻖ ‪GroupBy‬‬
‫ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﯩﻨﻰ ﺋﯩﻘﺘﯩـــﺪﺍﺭﯨﻨﻰ ﺋﯩﺸﻠﯩﺘﻪﻟﻪﻳـــﺴﯩﺰ‪ .‬ﻣﻪﺳــﯩﻠﻪﻥ ﻛـــﻮﺩ ‪ 4.17‬ﺩﯨﻜـــﻰ ﻣﻪﺳـــﯩﻠﻪ ﺋﯜﭼـــﯜﻥ‬
‫ﺗﯚﯞﻩﻧﺪﯨﻜﯩﻤﯘ ﺋﯜﻧﯜﻣﻠﯜﻙ‪:‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 50

4.17 ‫ﻛﻮﺩ‬

var expr = 
    from  c in customers 
    group c by c.Country; 
 
foreach(IGrouping<Countries, Customer> 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<Countries, string> 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
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪51‬‬

‫‪ Join‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﮬﻪﻣﺪﻩﻡ(‬
‫‪ Join‬ﻣﻪﺷـــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ‪ Linq‬ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﺋﯩﭽﯩـــﺪﯨﻜﻰ ﺗﯩﺰﻣﯩﻠﯩـــﺮﻯ ﺋﺎﺭﯨـــﺴﯩﺪﯨﻜﻰ ﻣﯘﻧﺎﺳـــﯩﯟﻩﺗﻨﻰ‬
‫ﺑﻪﻟﮕﯩﻠﻪﺷــﻜﻪ ﺋﯩــﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪ SQL .‬ﺳــﺎﻧﺪﺍﻥ ﻣﻪﺷــﻐﯘﻻﺗﯩﻨﻰ ﺋﯧﻠﯩــﭗ ﺋﯧﻴﺘــﺴﺎﻕ ﺋﺎﺳﺎﺳــﻪﻥ ﮬﻪﺭﻗﺎﻧــﺪﺍﻕ‬
‫ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺑﯩـﺮ ﻳـﺎﻛﻰ ﺑﯩﺮﻗـﺎﻧﭽﻪ ﺟﻪﺩﯞﻩﻟﻨـﻰ ﮬﻪﻣﺪﻩﻣﻠﻪﺷـﺘﯜﺭﯨﺪﯗ‪ Linq .‬ﺩﺍ‪ ،‬ﺑﯩـﺮ ﻗﯩـﺴﯩﻢ ﮬﻪﻣـﺪﻩﻡ‬
‫ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﻳﯘﻗﯩﺮﯨﻘﯩﺪﻩﻙ ﺧﯘﻟﻘﻨﻰ ﺋﯚﺯﯨﮕﻪ ﻣﯘﺟﻪﺳﺴﻪﻣﻠﻪﺷﺘﯜﺭﮔﻪﻥ‪.‬‬

‫‪) Join‬ﮬﻪﻣﺪﻩﻡ (‬
‫ﺷﻪﻙ‪-‬ﺷﯚﺑﯩﺴﯩﺰﻛﻰ ‪ Join‬ﺑﻮﻟﺴﺎ ﮬﻪﻣﺪﻩﻡ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﯩﭽﯩـﺪﯨﻜﻰ ﺗـﯘﻧﺠﻰ ﻣﻪﺷـﻐﯘﻻﺗﭽﻰ‪ .‬ﺋﯘﻧﯩـﯔ‬
‫ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫‪public static IEnumerable<V> Join<T, U, K, V>( ‬‬
‫‪    this IEnumerable<T> outer, ‬‬
‫‪    IEnumerable<U> inner, ‬‬
‫‪    Func<T, K> outerKeySelector, ‬‬
‫‪    Func<U, K> innerKeySelector, ‬‬
‫‪    Func<T, U, V> resultSelector); ‬‬
‫‪public static IEnumerable<V> Join<T, U, K, V>( ‬‬
‫‪    this IEnumerable<T> outer, ‬‬
‫‪    IEnumerable<U> inner, ‬‬
‫‪    Func<T, K> outerKeySelector, ‬‬
‫‪    Func<U, K> innerKeySelector, ‬‬
‫‪    Func<T, U, V> resultSelector, ‬‬
‫‪    IEqualityComparer<K> comparer); ‬‬

‫‪ Join‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﺩﺍ ﺗﯚﺕ ﺩﺍﻧﻪ ﻛﯚﭘﻤﺎﺱ ﺗﯩﭙﻨﯩﯔ ﻳﻮﻟﻠﯩﻨﯩﺸﯩﻨﻰ ﺗﻪﻟﻪﭖ ﻗﯩﻠﯩﺪﯗ‪ T .‬ﺑﻮﻟـﺴﺎ‬
‫ﺳﯩﺮﺗﻘﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﺎ ﺗﯩﭙﯩﻐﺎ ﯞﻩﻛﯩﻠﻠﯩﻚ ﻗﯩﻠﯩﺪﯗ‪ U ،‬ﺑﻮﻟﺴﺎ ﺋﯩﭽﻜﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣـﺎ ﺗﯩﭙﯩﻨـﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﻳـﺪﯗ‪.‬‬
‫‪ outerKeySelector‬ﺑﯩـﻠﻪﻥ ‪ innerKeySelector‬ﻻﺭ ﺑﻮﻟـﺴﺎ ﺳـﯩﺮﺗﻘﻰ ﯞﻩ ﺋﯩﭽﻜـﻰ ﻣﻪﻧـﺒﻪ‬ ‫ﻛﯚﺭﺳـﻪﺗﻤﻪ‬
‫ﺗﯩﺰﻣﯩﻠﯩﺮﯨــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﯩــﯔ ﺋــﺎﭼﻘﯘﭼﻠﯘﻕ ﺳــﯚﺯﻟﯩﺮﯨﻨﻰ ﻗﺎﻧــﺪﺍﻕ ﭘﻪﺭﻕ ﺋﯧﺘﯩــﺸﻨﻰ ﺋﯧﻴﺘﯩــﭗ ﺑﯧﺮﯨــﺪﯗ‪ .‬ﺑــﯘ‬
‫ﺋﺎﭼﻘﯘﭼﻠﯘﻕ ﺳﯚﺯﻟﻪﺭﻧﻰ ﮬﻪﺭ ﺋﯩﻜﻜﯩﻠﯩﺴﻰ ‪ K‬ﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﯘﭖ‪ Join ،‬ﺋﯘﻻﺭﻧﯩﯔ ﺗﻪﯕﻠﯧﻜﯩﻨﻰ ﺋﯚﺯﯨﮕﻪ ﺷﻪﺭﺕ‬
‫ﻗﯩﻠﯩﺪﯗ‪ V .‬ﺑﻮﻟﺴﺎ ﺋﺎﯓ ﺋﺎﺧﯩﺮﯨﻘﻰ ﻛﯚﭘﻤﺎﺱ ﺗﯩﭗ ﺑﻮﻟﯘﭖ ﺋﯘ ‪ Join‬ﻧﯩﯔ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩـﺴﯩﺪﯨﻜﻰ ﮬﻪﺭﺑﯩـﺮ‬
‫ﺋﻪﺯﺍﻧﯩﯔ ﺗﯩﭙﯩﻨﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﻳﺪﯗ‪.‬‬

‫‪ Join‬ﻧﯩﯔ ﺋﯩﻜﻜﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﺳﯧﻠﯩﺸﺘﯘﺭﻏﯘﭼﻘﺎ ﺋﻮﺭﯗﻥ ﺑﯧﺮﯨﻠﮕﻪﻥ ﺑﻮﻟﯘﭖ‪ ،‬ﮬﻪﻣﺪﻩﻣﻠﻪﺷـﻤﻪﻛﭽﻰ‬


‫ﺑﻮﻟﻐــﺎﻥ ﺋﯩﻜﻜــﻰ ﺗﯩﺰﻣﯩﻨﯩــﯔ ﺋــﺎﭼﻘﯘﭼﻠﯘﻕ ﺳــﯚﺯﻟﯩﺮﯨﻨﻰ ﺳﯧﻠﯩــﺸﺘﯘﺭﺷﻘﺎ ﺋﯩــﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪ .‬ﺑﯘﻧﯩــﯔ ﺋــﺎﺭﻗﯩﻠﯩﻖ‬
‫ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﻕ ﻗﺎﺋﯩﺪﯨــﺴﯩﻨﻰ ﺧﺎﺳﻼﺷﺘﯘﺭﺍﻻﻳــﺴﯩﺰ‪ .‬ﺋﻪﮔﻪﺭ ﻣﻪﺯﻛــﯘﺭ ﭘﺎﺭﺍﻣﯧﺘﯩﺮﻏــﺎ ‪ Null‬ﺑﯧﺮﯨﻠــﺴﻪ ﻳــﺎﻛﻰ‬
‫ﺑﯩﺮﻧﭽــﻰ ﺧﯩــﻞ ﺋﻪﻧﺪﯨﺰﯨــﺴﻰ ﺋﯩﺸﻠﯩﺘﯩﻠــﺴﻪ ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﺵ ﺋﯜﭼــﯜﻥ ﻛﯚﯕﯜﻟــﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗــﻜﻪ ﺑﻪﻟﮕﯩــﻠﻪﭖ‬
‫ﻗﻮﻳﯘﻟﻐﺎﻥ ﺳﯧﻠﺸﺘﯘﺭﻏﯘﭼﻰ ‪ EqualityComparer<TKey>.Default‬ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪.‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 52

‫ ﺧﯧﺮﯨــﺪﺍﺭﻻﺭﻧﻰ ﺋﯘﻻﺭﻧﯩــﯔ ﺯﺍﻛــﺎﺯﻟﯩﺮﻯ ﯞﻩ‬.‫ ﻧــﻰ ﻣﯩــﺴﺎﻝ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﭼﯜﺷــﯜﻧﯜﭖ ﺑﺎﻗــﺎﻳﻠﻰ‬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 }; 
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 53

‫ﻳﯘﻗﯩﺮﯨﻘﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﺪﻩ ﺩﯨﻘﻘﻪﺕ ﻗﯩﻠﯩﺸﻘﺎ ﺗﯩﮕﯩﺸﻠﯩﻚ ﻳﯧﺮﻯ ﺷﯘﻛﻰ‬


(o.IdProduct equals p.IdProduct)
‫ ﺳــﯩﺮﺗﻘﻰ ﺗﯩﺰﻣــﺎ ﺑﺎﺷــﺘﺎ ﺋﯩﭽﻜــﻰ ﺗﯩﺰﻣــﺎ‬:‫ ﻳﻪﻧــﻰ‬.‫ﺑــﯘ ﺋﯩﻜﻜﯩــﺴﯩﻨﯩﯔ ﺗﻪﺭﺗﯩﭙﻨــﻰ ﺋﯚﺯﮔﻪﺭﺗﯩــﺸﻜﻪ ﺑﻮﻟﻤﺎﻳــﺪﯗ‬
.‫ﺋﺎﺧﯩﺮﯨﺪﺍ ﻛﯧﻠﯩﺸﻰ ﻛﯧﺮﻩﻙ‬

‫ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ‬GroupJoin
‫ ﻏـﺎ ﺋﻮﺧﺸﯩـﺸﯩﭗ ﻛﯧﺘﯩـﺪﯨﻐﺎﻥ‬RIGHT OUTER JOIN ‫ ﻳـﺎﻛﻰ‬LEFT OUTER JOIN ‫ ﺩﯨﻜـﻰ‬Sql
.‫ ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﻳﺎﺧــﺸﻰ ﺗــﺎﻟﻼﺵ‬GroupJoin .‫ﺋﯩﻘﺘﯩــﺪﺍﺭﻧﻰ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﯗﺵ ﺋﯜﭼــﯜﻥ‬
:‫ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯖﻜﯩﮕﻪ ﺋﯩﺘﺎﻳﯩﻦ ﺋﻮﺧﺸﯩﺸﯩﭗ ﻛﯧﺘﯩﺪﯗ‬Join ‫ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ‬
public static IEnumerable<V> GroupJoin<T, U, K, V>( 
    this IEnumerable<T> outer, 
    IEnumerable<U> inner, 
    Func<T, K> outerKeySelector, 
    Func<U, K> innerKeySelector, 
    Func<T, IEnumerable<U>, V> resultSelector); 
public static IEnumerable<V> GroupJoin<T, U, K, V>( 
    this IEnumerable<T> outer, 
    IEnumerable<U> inner, 
    Func<T, TKey> outerKeySelector, 
    Func<U, TKey> innerKeySelector, 
    Func<T, IEnumerable<U>, V> resultSelector, 
    IEqualityComparer<TKey> 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); }} 
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 54

:‫ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ ﻳﯘﻗﯩﺮﯨﻘﻰ ﺟﯜﻣﻠﯩﻠﻪﺭﻧﯩﯔ ﺋﯩﺠﺮﺍ ﻧﻪﺗﯩﺠﯩﺴﻰ‬


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 }; 
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪55‬‬

‫‪ Set‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﺗﻮﭘﻼﻡ(‬
‫‪ Linq‬ﺳﻪﭘﯩﺮﯨﻤﯩﺰ ﺋﯘﭼﯘﺭ ﺗﯩﺰﻣﯩﻠﯩﺮﯨﻐﺎ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﯩﺪﯨﻐﺎﻥ »ﺑﯩﺮﯨﻜﻤﯩﺴﻰ«‪» ،‬ﻛﻪﺳﻤﯩﺴﻰ« ﯞﻩ »ﺩﯨـﻦ‬
‫ﺑﺎﺷﻘﺎ« ﻻﺭﺩﻩﻙ ﺋﻪﯓ ﺋﺎﺳﺎﺳﻰ ﻣﻪﺷﻐﯘﻻﺗﻼﺭﻏﺎ ﻛﯧﻠﯩﭗ ﻗﺎﻟﺪﻯ‪.‬‬

‫‪ Distinct‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ )ﺗﻪﻛﺮﺍﺭﻧﻰ ﺗﺎﺯﯨﻼﺵ(‬


‫ﺑﯩﺮﻗــﺎﻧﭽﻪ ﺧﯧﺮﯨــﺪﺍﺭ ﺋﻮﺧــﺸﺎﺵ ﺑﯩــﺮ ﻣﻪﮬــﺴﯘﻻﺗﻨﻰ ﺯﺍﻛــﺎﺯ ﻗﯩﻠﯩـﺸﻰ ﻣــﯘﻣﻜﯩﻦ‪ .‬ﺩﯦــﻤﻪﻙ ﺳــﯩﺰ ﺧﯧﺮﯨــﺪﺍﺭﻻﺭ‬
‫ﺯﺍﻛﺎﺯﻟﯩﺮﯨﺪﯨﻜﻰ ﻣﻪﮬﺴﯘﻻﺗﻼﺭﻧﻰ ﺋﻮﻗﯘﭖ ﭼﯩﻘﺴﯩﯖﯩﺰ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩﺴﯩﺪﺍ ﺗﻪﻛﺮﺍﺭ ﺋﻪﺯﺍ ﻛﯚﺭﯛﻟﯩـﺸﻰ ﻣـﯘﻣﻜﯩﻦ‪.‬‬
‫ﻣﯘﺷﯘ ﺧﯩﻞ ﺗﻪﻛﺮﺍﺭﻟﯩﻘﻨﯩﯔ ﺋﺎﻟﺪﯨﻨﻰ ﺋﯧﻠﯩﺶ ﺋﯜﭼﯜﻥ ﻗﺎﻧﺪﺍﻕ ﻗﯩﻠﯩﺶ ﻛﯧﺮﻩﻙ؟ ﻣﯘﺷـﯘ ﺧﯩـﻞ ﻣﻪﺳـﯩﻠﻪ ‪Sql‬‬
‫ﺟﯜﻣﻠﯩﺴﯩﺪﻩ ﺋﺎﺩﻩﺗﺘﻪ ‪ Join‬ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻰ ﺋﯩﭽﯩﺪﻩ ‪ DISTINCT‬ﺧﺎﺱ ﺳـﯚﺯﯨﻨﻰ ﺋﯩـﺸﻠﯩﺘﯩﺶ ﺋـﺎﺭﻗﯩﻠﯩﻖ‬
‫ﮬﻪﻝ ﻗﯩﻠﯩﻨﺎﺗﺘﻰ‪ Linq .‬ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻠﯩﺮﯨﺪﻩ ﺑﻮﻟﺴﺎ ﺑﯘﻧﯩﯔ ﺋﯜﭼﯜﻥ ﺗﻮﭘﻼﻡ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻧﯩﯔ ﺋﻪﺯﺍﺳـﻰ‬
‫ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﯩﻨﻰ ﺗﻪﻣﯩــﻨﻠﯩﮕﻪﻥ‪ .‬ﺋﯘﻧﯩــﯔ ﺋﻪﻧﺪﯨﺰﯨــﺴﻰ ﺋﯩﻨﺘــﺎﻳﯩﻦ ﺋــﺎﺩﺩﻯ ﺑﻮﻟــﯘﭖ‬ ‫ﺑﻮﻟﻐــﺎﻥ ‪Distinct‬‬
‫ﭘﻪﻗﻪﺕ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﻨﯩﻼ ﻗﻮﺑﯘﻝ ﻗﯩﻠﯩﭗ ﺋﯘﻧﯩـﯔ ﺋﻪﺯﺍﻟﯧـﺮﻯ ﺋﺎﺭﯨـﺴﯩﺪﯨﻜﻰ ﺋـﯚﺯﮔﯩﭽﻪ ﺋﻪﺯﺍﻻﺭﻧـﻰ ﻗـﺎﻳﺘﯘﺭﯗﭖ‬
‫ﺑﯧﺮﯨﺪﯗ‪.‬‬
‫‪ Distinct‬ﺋﯜﭼﯜﻥ ﺑﯩﺮ ﻣﯩﺴﺎﻝ ﻛﻮﺩ ‪ 4.24‬ﺩﻩ ﺑﯧﺮﯨﻠﺪﻯ‪.‬‬
‫‪public static IEnumerable<T> Distinct<T>( ‬‬
‫‪    this IEnumerable<T> 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 ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪56‬‬

‫‪                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‬ﻧﯩـﯔ‬
‫ﺗﻪﻛﺮﺍﺭﻻﺭﻧﻰ ﺳﯜﺯﯛﺵ ﺋﻪﮔﻠﯩﻜﯩﺪﯨﻦ)ﺋﻪﮔﻠﻪﻙ‪ :‬ﺋﺎﺋﯩﻠﯩﻠﻪﺭﺩﻩ ﺋـﯘﻥ ﺗﺎﺳﻘﺎﺷـﻘﺎ ﺋﯩـﺸﻠﯩﺘﯩﻠﯩﺪﯨﻐﺎﻥ ﺳـﯜﺯﮔﯜﭺ(‬
‫ﺋﯚﺗﯜﭖ ﻛﯧﺘﯩﺪﯗ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪57‬‬

‫ﻗﻮﺷﯘﻣﭽﻪ ﺳﺎﯞﺍﺕ ‪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; ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪58‬‬

‫‪        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‬ﺩﯨـــﻦ ﺑﺎﺷـــﻘﺎ( ﻣﻪﺷﻐﯘﻻﺗﭽﯩـــﺴﻰ ﺑﻮﻟـــﺴﺎ‪ ،‬ﺑﯩﺮﯨﻨﭽـــﻰ ﺗﯩﺰﻣﯩـــﺪﯨﻜﻰ ﺋﯩﻜﻜﯩﻨﭽـــﻰ ﺗﯩﺰﻣﯩـــﺪﺍ‬
‫ﺋﯘﭼﺮﯨﻤﺎﻳﺪﯨﻐﺎﻥ ﺋﻪﺯﺍﻻﺭﻧﻰ ﺋﺎﻟﯩﺪﯗ‪.‬‬
‫ﺑﯘﻻﺭﻏﯩﻤﯘ ﺗﻪﯕﺪﺍﺵ ﺑﻮﻟﻐﺎﻥ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺧﺎﺱ ﺳﯚﺯﻟﯩﺮﯨﻨﯩﯔ ﻳﻮﻗﻠﯩﻘﯩﻨﻰ ﺩﯦﮕﯩﻢ ﻛﻪﻟﻤﻪﻳﯟﺍﺗﯩﺪﯗ‪ .‬ﺑﯩﺮﺍﻕ‬
‫ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺪﻩﻙ ﺋﺎﺭﻻﺷﺘﯘﺭﯗﭖ ﺋﯩﺸﻠﯩﺘﻪﻟﻪﻳﻤﯩﺰ‪:‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 59

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
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪60‬‬

‫ﻳـﯘﻗﯩﺮﯨﻘﻰ ﭘﺮﻭﮔﺮﺍﻣﻤﯩـﺪﯨﻦ ﮬﺎﺳـﯩﻞ ﺑﻮﻟﻐـﺎﻥ ﻧﺎﻣـﺴﯩﺰ ﺗﯩﭙﻠﯩـﻖ ﺋﻮﺑﻴﯧﻜﯩﺘﻼﺭﻧﯩـﯔ ‪ OrdersCount‬ﻧـﺎﻣﻠﯩﻖ‬


‫ﺧﺎﺳﻠﯩﻘﯩﻨﯩﯔ ﻗﯩﻤﻤﯩﺘﻰ ﻣـﺎﺱ ﺧﯧﺮﯨـﺪﺍﺭﻧﯩﯔ ﺯﺍﻛـﺎﺯ ﺳـﺎﻧﯩﻨﻰ ﺋﺎﻟﯩـﺪﯗ‪ .‬ﺩﯦـﻤﻪﻙ‪ Count ،‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩـﺴﻰ‬
‫ﺷــﻪﻛﻠﯩﺪﻩ ﻗــﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﯨــﺪﯗ‪Count .‬‬ ‫‪int‬‬ ‫ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣــﺎ ﺋﯩﭽﯩــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﯩــﯔ ﺳــﺎﻧﯩﻨﻰ‬
‫ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﯩﻨﯩﯔ ﻳﻪﻧﻪ ﺑﯩــﺮ ﺧﯩــﻞ ﺋﻪﻧﺪﯨﺰﯨــﺴﻰ ﺑﻮﻟــﯘﭖ‪ ،‬ﺋــﯘ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﻣﻪﻟــﯘﻡ ﺷــﻪﺭﺗﻨﻰ‬
‫ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﮔﻪﻥ ﺋﻪﺯﺍﻻﺭ ﺳﺎﻧﯩﻨﻰ ﺗﯧﭙﯩﭗ ﺑﯧﺮﯨﺪﯗ‪ .‬ﻣﻪﺳﯩﻠﻪﻥ‪ :‬ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﺋﺎﺭﯨـﺴﯩﺪﺍ ﺯﺍﻛﺎﺯﻧﯩـﯔ ﺳـﺎﻧﻰ‬
‫ﺋﯩﻜﻜﯩﮕﻪ ﺗﻪﯓ ﺑﻮﻟﻐﺎﻧﻼﺭﻧﯩﯔ ﺳﺎﻧﯩﻨﻰ ﺗﯧﭙﯩﭗ ﺑﺎﻗﺎﻳﻠﻰ‪:‬‬
‫;)‪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<Numeric> source); ‬‬
‫‪public static Numeric Sum<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫;)‪    Func<T, Numeric> selector‬‬

‫ﺋﯘﻧﯩــﯔ ﻗﺎﻳﺘﻤــﺎ ﻗﯩﻤﻤﯩﺘــﻰ ﻳــﺎﻛﻰ ﺋﯩﻜﻜﯩﻨﭽــﻰ ﺋﻪﻧﺪﯨﺰﯨــﺪﯨﻜﻰ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮﻯ ﺑﻮﻟــﺴﯘﻥ ﺋﯘﻻﺭﻧﯩــﯔ ﺗﯩﭙــﻰ‬
‫‪ Numeric‬ﺋﯩﻜﻪﻥ‪ .‬ﺑﯘ ﻳﻪﺭﺩﯨﻜﻰ ‪ Numeric‬ﺑﻮﻟﺴﺎ »ﺳﺎﻧﻠﯩﻖ« ﺩﯦـﮕﻪﻥ ﻣﻪﻧﯩـﺪﻩ ﺑﻮﻟـﯘﭖ‪int, int?, ،‬‬
‫?‪ long, long?, float, float?, double, double?, decimal,decimal‬ﻻﺭﻧﯩﯔ ﺧﺎﻟﯩﻐﺎﻥ ﺑﯩﺮﯨﻨـﻰ‬
‫ﻛﯚﺭﺳﯩﺘﯩﺪﯗ‪ int .‬ﻏﯘ ﭘﯜﺗﯜﻥ ﺳﺎﻥ ﺗﯩﭙﻰ‪ ،‬ﺋﻪﻣﯩﺴﻪ ?‪ int‬ﭼﯘ؟‬
‫‪ C#2.0‬ﺩﯨــﻦ ﺗﺎﺭﺗﯩــﭗ ﻗﯩﻤﻤﻪﺗﻠﯩــﻚ ﺗﯩﭙﻠﯩــﻖ ﺋﯚﺯﮔﻪﺭﮔــﯜﭼﻰ ﻣﯩﻘــﺪﺍﺭﻻﺭﻏﺎ ﮬﯩــﭻ ﻗﺎﻧــﺪﺍﻕ ﻗﯩﻤــﻤﻪﺕ‬
‫ﻳﻮﻟﻼﻧﻤﺎﻳــﺪﯨﻐﺎﻥ ﮬــﺎﻟﻪﺗﻨﻰ ﺋﯩﭙــﺎﺩﯨﻠﻪﺵ ﺯﯙﺭﯛﺭﯨﻴﯩﺘﯩــﺪﯨﻦ)ﺑﻮﻟﯘﭘﻤــﯘ ﺳــﺎﻧﺪﺍﻧﺪﯨﻜﻰ ﻗــﯘﺭﯗﻕ ‪ int‬ﺗﯩﭙﯩﻐــﺎ‬
‫ﻣﺎﺳﻼﺷﺘﯘﺭﯗﺵ( ﺷﯘ ﺗﯩﭗ ﺧﺎﺱ ﺳﯚﺯﯨﻨﯩﯔ ﺋﺎﺭﻗﯩـﺴﯩﻐﺎ ﺳـﯘﺋﺎﻝ ﺑﻪﻟﮕﯩـﺴﻰ ﺋـﺎﺭﻗﯩﻠﯩﻖ )?‪ T‬ﺩﻩﻙ( ﻗـﯘﺭﯗﻕ‬
‫ﺑﻮﻻﻻﻳﺪﯨﻐﺎﻥ ﺗﯩﭗ ﮬﺎﻟﯩﺘﯩﻨﻰ ﺋﯩﭙﺎﺩﯨﻠﻪﻳﺪﯗ )ﺋﯘﻧﯩﯔ ﺗﯩﭙﻰ >‪ .(Nullable<T‬ﻣﻪﺳـﯩﻠﻪﻥ ?‪ int‬ﺋـﺎﺭﻗﯩﻠﯩﻖ‬
‫>‪ Nullable<System.Int32‬ﺋﯩﭙﺎﺩﯨﻠﯩﻨﯩـﺪﯗ‪ int? i; i=null; Console.WriteLine(i).‬ﺩﻩﻙ ﻳﯧـﺰﯨﺶ‬
‫ﺑﯘ ﻗﯘﺭﻻﺭ ﺗﻪﻛﺸﯜﺭﯛﺷﺘﯩﻦ ﺋﯚﺗﻤﻪﻳﺪﯗ‪.‬‬ ‫ﻣﯘﺗﻠﻪﻕ ﺋﯩﻨﺎﯞﻩﺗﻠﯩﻚ‪ .‬ﻟﯧﻜﯩﻦ ;)‪int i; Console.WriteLine(i‬‬
‫‪ Sum‬ﻧﯩﯔ ﺑﯩﺮﯨﻨﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ ﺳـﺎﻧﻠﯩﻖ ﺗﯩﭙﻠﯩـﻖ ﺩﻩﭖ ﻗﺎﺭﯨﻠﯩـﭗ ﺋﯘﻻﺭﻏـﺎ‬
‫ﺑﯩﯟﺍﺳﺘﻪ ﻗﻮﺷﯘﺵ ﺋﻪﻣﯩﻠﻰ ﺑﯧﺠﯩﺮﯨﭗ ﻳﯩﻐﯩﻨﺪﯨﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﻣﻪﻧﺒﻪ ﻗﯘﺭﯗﻕ ﺑﻮﻟﺴﺎ ﻧـﯚﻝ ﻗﺎﻳﺘﯩـﺪﯗ‪.‬‬
‫ﺋﻪﮔﻪﺭ ﺋﻪﺯﺍﻻﺭ ‪ null‬ﺑﻮﻻﻻﻳﺪﯨﻐﺎﻥ ﺗﯩﭙﻠﯩﻖ ﺑﻮﻟﯘﭖ ﮬﻪﻣﻤﯩﺴﯩﻨﯩﯔ ﻗﯩﻤﻤﯩﺘـﻰ ‪ null‬ﺑﻮﻟـﺴﺎ ﻧﻪﺗﯩﺠﯩـﺪﻩ ‪null‬‬
‫ﻗﺎﻳﺘﯩﺪﯗ‪ .‬ﻣﻪﺯﻛﯘﺭ ﺋﻪﻧﺪﯨﺰﻩ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﻰ ﺑﯩﯟﺍﺳﺘﻪ ﻗﻮﺷﻘﯩﻠﻰ ﺑﻮﻟﯩﺪﯨﻐﺎﻥ ﺋﻪﮬﯟﺍﻝ ﺋﺎﺳـﺘﯩﺪﺍ‬
‫ﺋﯩـــﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪ .‬ﻣﻪﺳـــﯩﻠﻪﻥ‪ :‬ﻣﻪﻧـــﺒﻪ ﺗﯩﺰﻣـــﺎ ﺳـــﺎﻧﻼﺭ ﮔﯘﺭﭘﯩـــﺴﻰ ﺗﯩﭙﻠﯩـــﻖ ﺑﻮﻟـــﺴﺎ‪ ،‬ﺗﯚﯞﻩﻧﺪﯨﻜﯩـــﺪﻩﻙ‬
‫ﺋﯩﺸﻠﯩﺘﻪﻟﻪﻳﻤﯩﺰ‪:‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 61

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 
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 62

           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 
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪63‬‬

‫‪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<Numeric> source); ‬‬
‫‪public static T Min<T>/Max<T>( ‬‬
‫‪    this IEnumerable<T> source); ‬‬
‫‪public static Numeric Min<T>/Max<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, Numeric> selector); ‬‬
‫‪public static S Min<T, S>/Max<T, S>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, S> selector); ‬‬

‫ﺑﯩﺮﯨﻨﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﺋﻪﺯﺍﻻﺭﻏﺎ ﻧﯩـﺴﺒﻪﺗﻪﻥ ﺋـﺎﺭﺧﯩﻤﯩﺘﯩﻜﯩﻠﯩﻖ ﺳﯧﻠﯩـﺸﺘﯘﺭﯗﺵ ﺋﯧﻠﯩـﭗ ﺑﺎﺭﯨـﺪﯗ‪ .‬ﺷـﯘﯕﺎ‬


‫ﻣﻪﺯﻛﯘﺭ ﺋﻪﻧﺪﯨﺰﯨﻨﻰ ﺋﻪﺯﺍﻟﯧﺮﻯ ﺳـﺎﻥ ﺑﻮﻟﻐـﺎﻥ ﺗﯩﺰﻣﻼﺭﻏـﺎ ﺋﯩـﺸﻠﯩﺘﯩﺶ ﻣﯘﯞﺍﭘﯩـﻖ‪ .‬ﻣﻪﺳـﯩﻠﻪﻥ‪ :‬ﺗﯚﯞﻩﻧـﺪﯨﻜﻰ‬
‫ﻣﯩﺴﺎﻟﺪﺍ ﺑﺎﺭﻟﯩﻖ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ﺑﺎﺭﻟﯩﻖ ﺯﺍﻛﺎﺯﻟﯩﺮﯨﻨﯩﯔ ﻣﯩﻘـﺪﺍﺭﯨﻐﺎ ﻧﯩـﺴﺒﻪﺗﻪﻥ ﺋﻪﯓ ﻛﯩﭽﯩﻜﯩﻨـﻰ ﺗﯧـﭙﯩﺶ‬
‫ﻣﻪﺷﻐﯘﻻﺗﻰ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﯩﺪﯗ‪:‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪64‬‬

‫ﻛﻮﺩ ‪4.32‬‬

‫‪var expr = ‬‬
‫‪    (from c in customers ‬‬
‫‪         from   o in c.Orders ‬‬
‫‪         select o.Quantity ‬‬
‫‪    ).Min(); ‬‬

‫ﺋﯩﻜﻜﯩﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﯨﺪﻩ ﺋﻪﺯﺍﻻﺭﻧﯩـﯔ ﺗﯩﭙﯩﻨـﻰ ﺋﯧﺘﯩﯟﺍﺭﻏـﺎ ﺋﺎﻟﻤـﺎﻱ ﭼـﻮﯓ‪ -‬ﻛﯩﭽﯩﻜﯩﻨـﻰ ﺗﺎﭘﯩـﺪﯗ‪.‬‬
‫)ﺋﻪﻟﯟﻩﺗﺘﻪ‪ ،‬ﭼﻮﯓ‪ -‬ﻛﯩﭽﯩﻜﯩﻨﻰ ﺗﯧﭙﯩﺶ ﺋﯜﭼﯜﻥ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺵ ﺋﯧﻠﯩـﭗ ﺑﯧـﺮﯨﺶ ﻛﯧـﺮﻩﻙ( ﺋﻪﮔﻪﺭ ﻣﻪﻧـﺒﻪ‬
‫ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﺋﻪﺯﺍ ﺗﯩﭙــﻰ >‪ IComparable<T‬ﻧــﻰ )ﻳــﺎﻛﻰ ‪ IComparable‬ﻧــﻰ( ﻗﻮﻟﻠﯩــﺴﺎ ﻣﯘﺷــﯘﻧﯩﯔ‬
‫ﺋﻪﻣﻪﻟﯩﻠﻪﺷﺘﯜﺭﯛﻟﯜﺷﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺳﯧﻠﯩـﺸﺘﯘﺭﯗﺵ ﻗﯩﻠﯩـﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﻳـﯘﻗﯩﺮﯨﻘﻰ ﺋﯩﻜﻜﯩـﻼ ﺋﯧﻐﯩﺰﻧـﻰ ﺋﻪﻣﻪﻟـﮕﻪ‬
‫ﺋﺎﺷﯘﺭﻣﯩﻐﺎﻥ ﺑﻮﻟﺴﺎ ‪ ArgumentException‬ﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ)‪异常‬ﻧﻰ ﻣﯘﺷـﯘﻧﺪﺍﻕ ﺋﺎﺗـﺎﭖ ﺗـﯘﺭﺩﯗﻡ(‬
‫ﻗﻮﻳﯘﭖ ﺑﯧﺮﯨﺪﯗ‪ .‬ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﺧﺎﺗﺎﻟﯩﻖ ﺋﯘﭼﯘﺭﯨﻨﯩﯔ ﺋﺎﺳﺎﺳﻰ ﻣﻪﺯﻣـﯘﻧﻰ ﻣﯘﻧـﺪﺍﻕ‪» :‬ﻛﻪﻡ ﺩﯦﮕﻪﻧـﺪﻩ ﺑﯩـﺮ‬
‫ﺩﺍﻧﻪ ﺋﻮﺑﻴﯧﻜﯩﺖ ‪ IComparable‬ﺋﯧﻐﯩﺰﯨﻨﻰ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ ﺑﻮﻟﯘﺷﻰ ﻛﯧﺮﻩﻙ‪«.‬‬
‫ﺩﻩﻟﯩﻠــﻰ ﺋﯜﭼــﯜﻥ ﻛــﻮﺩ ‪ 4.33‬ﺩﯨﻜﯩ ـﺪﻩﻙ ﻛــﻮﺩ ﻳﯧﺰﯨــﭗ ﻗﻪﺳــﺘﻪﻥ ﺑﯩﻨﻮﺭﻣــﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨﻠــﺪﻯ‪ .‬ﻣﻪﺯﻛــﯘﺭ‬
‫ﻛﻮﺩﺩﯨﻜﻰ ﺧﺎﺗﺎﻟﯩﻖ ﺳﻪﯞﻩﺑﻰ ﺷﯘﻛﻰ‪ ،‬ﮔﻪﺭﭼﻪ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩﺴﻰ ﺯﺍﻛـﺎﺯ ﻣﯩﻘـﺪﺍﺭﯨﻨﯩﯔ ﺗـﻮﭘﻠﯩﻤﻰ ﺑﻮﻟـﺴﯩﻤﯘ‬
‫ﻟﯧﻜﯩﻦ ﻛﻮﺩ ‪ 71‬ﺩﯨﻜﻰ ﺳﯜﺭﯛﺷﺘﯜﻛﺘﯩﻦ ﭘﻪﺭﻗﻠﯩﻨﯩﺪﯗ‪ .‬ﻳﻪﻧـﻰ ﺋﺎﻟﺪﯨﻨﻘﯩـﺴﯩﺪﯨﻜﻰ ﭼـﺎﺭﻻﺵ ﻧﻪﺗﯩﺠﯩـﺴﯩﻨﯩﯔ‬
‫ﺗﯩﭙﻰ ﺳﺎﻧﻼﺭ ﮔﯘﺭﭘﯩﺴﻰ‪ .‬ﻛﯧﻴﯩﻨﻜﯩﺴﯩﻨﯩﯩﯔ ﺑﻮﻟﺴﺎ ﺑﯩﺮﻻ ﺳﺎﻧﻠﯩﻖ ﻗﯩﻤﻤﻪﺗﻠﯩـﻚ ﺧﺎﺳـﻠﯩﻘﻰ ﺑﻮﻟﻐـﺎﻥ ﻧﺎﻣـﺴﯩﺰ‬
‫ﺗﯩﭙﻠﯩﻖ ﺋﻪﺯﺍﻻﺭ ﺗﻮﭘﻠﯩﻤﻰ‪ .‬ﻧﺎﻣـﺴﯩﺰ ﺗﯩـﭙﻼﺭ ﺑﯩـﺮﺩﻩﻙ ﺳﯧﻠﯩـﺸﺘﯘﺭﯗﺵ ﺋﯧﻐﯩﺰﻟﯩﺮﯨﻨـﻰ ﺋﻪﻣﻪﻟـﮕﻪ ﺋﺎﺷـﯘﺭﻣﯩﻐﺎﻥ‬
‫ﺑﻮﻟﯩﺪﯗ‪.‬‬
‫ﻛﻮﺩ ‪ 4.33‬ﺯﻭﺭﻻﭖ ﺗﯩﭗ ﺧﺎﺗﺎﻟﯩﻘﻰ ﺳﻪﯞﻩﺑﻠﯩﻚ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨﺶ‬

‫‪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‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪65‬‬

‫‪ Average‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ‬
‫ﻣﻪﺯﻛﯘﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﻰ ﺋﻪﺯﺍ ﻗﯩﻤﻤﻪﺗﻠﯩﺮﻧﯩﯔ ﺋﻮﺗﺘﯘﺭﭼﻪ ﻗﯩﻤﻤﯩﺘﯩﻨﻰ ﺗﺎﭘﯩﺪﯗ‪ .‬ﺋﯘ ﺋﺎﻟﺪﯨﺪﺍ ﺳﯚﺯﻟﯩﮕﻪﻥ ‪Max,‬‬
‫‪ Min, Sum‬ﻻﺭﻏــﺎ ﺋﻮﺧــﺸﺎﺵ ﺋﻪﺯﺍﻻﺭﻧﯩــﯔ ﻗﯩﻤﻤﻪﺗﻠﯩــﻚ ﺗﯩــﭗ ﺑﻮﻟﻐــﺎﻥ ﮬــﺎﻟﯩﺘﯩﮕﻪ ﻣﯘﯞﺍﭘﯩــﻖ‪ .‬ﺋﯘﻧــﺪﺍﻕ‬
‫ﺑﻮﻟﻤﯩﻐــﺎﻥ ﺋﻪﮬــﯟﺍﻝ ﺋﺎﺳــﺘﯩﺪﺍ ﺑﺎﺷــﻘﺎ ﺋﻪﻧــﺪﯨﺰﯨﻠﯩﺮﻯ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﻛــﯚﭖ ﺧﺎﺳــﻠﯩﻖ ﭼﺎﻗﯩﺮﯨﻠﻤــﺎ ﺗﯩﭙﻨﯩــﯔ‬
‫ﻗﯩﻤﻤﻪﺗﻠﯩﻚ ﺧﺎﺳﻠﯩﻘﯩﻨﻰ ﺑﻪﻟﮕﯩﻠﻪﭖ ﻗﻮﻳﯘﺵ ﻛﯧـﺮﻩﻙ‪ .‬ﺷـﯘﻧﺪﯨﻼ ﻧﻮﺭﻣـﺎﻝ ﻣﻪﺷـﻐﯘﻻﺕ ﺋﯧﻠﯩـﭗ ﺑﺎﺭﺍﻻﻳـﺪﯗ‪.‬‬
‫ﺋﯘﻧﯩﯔ ﺗﯚﯞﻩﻧﺪﻩ ﻛﯚﺭﺳﯩﺘﯩﻠﮕﻪﻧﺪﻩﻙ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺑﺎﺭ‪:‬‬
‫‪public static Result Average( ‬‬
‫‪    this IEnumerable<Numeric> source); ‬‬
‫‪public static Result Average<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫;)‪    Func<T, Numeric> 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‬ﺋﯩﭙﺎﺩﯨــﺴﻰ‬
‫ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﻪﻟﮕﯩﻠﻪﭖ ﺑﯧﺮﯨﺸﯩﻤﯩﺰ ﻛﯧﺮﻩﻙ‪.‬‬
‫ﺗﯚﯞﻩﻧﺪﻩ ﺑﺎﺭﻟﯩﻖ ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﯞﻩ ﺋﯘﻻﺭﻧﯩﯔ ﺯﺍﻛـﺎﺯ ﻣﯩﻘـﺪﺍﺭﻟﯩﺮﯨﻨﯩﯔ ﺋﻮﺗﺘـﯘﺭﭼﻪ ﻗﯩﻤﻤﯩﺘﯩﻨـﻰ ﭼﯩﻘﯩﺮﯨـﺪﯨﻐﺎﻥ‬
‫ﻣﯩﺴﺎﻝ ﺑﯧﺮﯨﻠﺪﻯ‪:‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 66

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}
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪67‬‬

‫‪ Generation‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﻗﯘﺭﻏﯘﭺ(‬
‫ﻣﻪﺳﯩﻠﻪﻥ ‪-2000‬ﻳﯩﻠﯩﺪﯨﻦ ‪-2007‬ﻳﯩﻠﯩﮕﯩﭽﻪ ﺑﻮﻟﻐـﺎﻥ ﺋـﺎﺭﻟﯩﻘﺘﯩﻜﻰ ﺯﺍﻛـﺎﺯﻻﺭ ﺗﯩﺰﯨﻤﻠﯧﻜﯩﻨـﻰ ﭼﯩﻘﯩـﺮﯨﺶ‪،‬‬
‫ﻳﺎﻛﻰ ﺋﻮﺧﺸﺎﺵ ﺑﯩﺮ ﺋﯘﭼﯘﺭﻏﺎ ﺋﻮﺧـﺸﺎﺵ ﺑﯩـﺮ ﻣﻪﺷـﻐﯘﻻﺗﻨﻰ ﺗﻪﻛـﺮﺍﺭ ﺋﯧﻠﯩـﭗ ﺑﯧﺮﯨـﺸﺘﻪﻙ ﻣﻪﺷـﻐﯘﻻﺗﻼﺭﻧﻰ‬
‫ﻗﯘﺭﻏﯘﭺ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﯩﻨﺘﺎﻳﯩﻦ ﺋﻪﭘﭽﯩﻠﻠﯩﻚ ﺑﯩﻠﻪﻥ ﺋﯧﻠﯩﭗ ﺑﺎﺭﺍﻻﻳﺪﯗ‪.‬‬

‫‪) Range‬ﺩﺍﺋﯩﺮﻩ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ(‬


‫ﺋــﯘ ﺑﻪﻟﮕﯩﻠﯩــﻚ ﺩﺍﺋﯩﺮﯨــﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗــﻠﻪﺭ ﺗﯩﺰﻣﯩــﺴﻰ ﮬﺎﺳــﯩﻞ ﻗﯩﻠﯩــﭗ ﺑﯧــﺮﯨﺶ ﺭﻭﻟﯩﻐــﺎ ﺋــﯧﮕﻪ ﺑﻮﻟــﯘﭖ‪،‬‬
‫ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺑﯩﺮﺩﯨﻦ‪ -‬ﺑﯩﺮ ﺋﻪﻧﺪﯨﺰﯨﮕﻪ ﺋﯩﮕﻪ‪:‬‬
‫‪public static IEnumerable<int> 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)); } ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪68‬‬

‫‪) 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‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪69‬‬

‫‪) Empty‬ﻗﯘﺭﯗﻕ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ(‬


‫ﻣﻪﺯﻛﯘﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﻰ ﻣﻪﻟﯘﻡ ﺗﯩﭙﻠﯩﻖ ﺋﻪﺯﺍﻧﯩﯔ ﻗﯘﺭﯗﻕ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﻗـﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﻩﻟﻪﻳـﺪﯗ‪ .‬ﻳﻪﻧـﻰ ﻗـﯘﺭﯗﻕ‬
‫ﺗﯩﺰﻣﺎ ﮬﺎﺳﯩﻞ ﻗﯩﻠﯩﺸﺘﺎ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪ .‬ﻣﻪﺳﯩﻠﻪﻥ‪:‬‬
‫ﻛﻮﺩ ‪ Empty 4.43‬ﺩﯨﻦ ﭘﺎﻳﺪﯨﻠﯩﻨﯩﭗ ﺧﯧﺮﯨﺪﺍﺭ ﺗﯩﭙﯩﻨﯩﯔ ﻗﯘﺭﯗﻕ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﮬﺎﺳﯩﻞ ﻗﯩﻠﯩﺶ‬

‫‪IEnumerable<Customer> customers = Enumerable.Empty<Customer>(); ‬‬

‫‪ Quantifiers‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ )ﻣﯩﻘﺪﺍﺭ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ(‬


‫ﺗﯩﺰﻣــﺎ ﺋﯩﭽﯩــﺪﻩ ﻣﻪﻟــﯘﻡ ﺷــﻪﺭﺗﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨــﺪﯨﻐﺎﻥ ﺋﻪﺯﺍﻧﯩــﯔ ﺑــﺎﺭ‪ -‬ﻳــﻮﻗﻠﯩﻘﯩﻨﻰ ﺗﻪﻛــﺸﯜﺭﯛﺷﻤﯘ‬
‫ﺋﯩﮫﯩﺘﯩﻴﺎﺟﯩﯩﻤﯩﺰﻧﯩــﯔ ﺳــﯩﺮﺗﯩﺪﺍ ﺋﻪﻣﻪﺱ‪ .‬ﮔﻪﺭﭼﻪ ﺑﯘﻧــﺪﺍﻕ ﻣﻪﺳــﯩﻠﯩﻠﻪﺭﻧﻰ ﺑﯩــﺰ ﺋﺎﻟــﺪﯨﻨﻘﻰ ﻣﻪﺯﻣــﯘﻧﻼﺭﺩﺍ‬
‫ﺳــﯚﺯﻟﻪﭖ ﺋــﯚﺗﻜﻪﻥ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻼﺭﻧﻰ ﺑﯩﺮﻟﻪﺷــﺘﯜﺭﯛﺭﭖ ﺋﯩــﺸﻠﯩﺘﯩﺶ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﻏﯩﻠﻰ‬
‫ﺑﻮﻟﯩﺴﯩﻤﯘ‪ ،‬ﻟﯧﻜﯩﻦ ‪ Linq‬ﻣﯘﺷﯘﻧﺪﺍﻕ ﺋﻪﮬﯟﺍﻟﻼﺭﻏﺎ ﺧﺎﺱ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭﻧﻰ ﺗﻪﻣﯩﻨﻠﯩﮕﻪﻥ‪.‬‬

‫‪ Any‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ‬
‫ﺗﻮﻧﯘﺷﺘﯘﺭﻣﺎﻗﭽﻰ ﺑﻮﻟﻐﺎﻥ ﺗـﯘﻧﺠﻰ ﻣﻪﺷـﻐﯘﻻﺗﭽﻰ ‪ Any‬ﺑﻮﻟـﯘﭖ‪ ،‬ﺋـﯘ ﺑﯧـﺮﯨﻠﮕﻪﻥ ﺭﺍﺱ‪ -‬ﻳﺎﻟﻐـﺎﻥ ﺗﯩﭙﻠﯩـﻖ‬
‫ﻛﯚﺭﺳﻪﺗﻤﯩﮕﻪ ﺋﺎﺳﺎﺳﻪﻥ ﺭﺍﺱ‪ -‬ﻳﺎﻟﻐﺎﻧﻠﯩﻖ ﻗﯩﻤﻤﻪﺕ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ‪ .‬ﺗﯚﯞﻩﻧﺪﯨﻜﯩﻠﻪﺭ ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ‪:‬‬
‫‪public static bool Any<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, bool> predicate); ‬‬
‫‪public static bool Any<T>( ‬‬
‫;)‪    this IEnumerable<T> source‬‬

‫ﻳﯘﻗﯩﺮﯨﻘﻰ ﻣﯧﺘﻮﺩ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﯨﻨﻰ ﻛـﯚﺭﮔﯩﻨﯩﯖﯩﺰﺩﻩ‪ ،‬ﻛﺎﻟﻠﯩﯖﯩﺰﻏـﺎ »ﻣﻪﻧـﺒﻪﺩﯨﻦ ﺑﺎﺷـﻘﺎ ﮬﯧﭽﻘﺎﻧـﺪﺍﻕ ﺷـﻪﺭﺕ‬


‫ﻗﻮﺑﯘﻝ ﻗﯩﻠﻤﺎﻳﺪﯨﻐﺎﻥ ﻣﯧﺘﻮﺩ ﺷﻪﻛﻠﻰ ﻧـﯧﻤﯩﮕﻪ ﺋﺎﺳـﺎﻥ ﺭﺍﺳـﺖ‪ -‬ﻳﺎﻟﻐـﺎﻥ ﻗﯩﻤـﻤﻪﺕ ﻗﺎﻳﺘﯘﺭﯨـﺪﯗ؟« ﺩﯦـﮕﻪﻥ‬
‫ﺳﯘﺋﺎﻝ ﻛﯧﻠﯩـﺸﻰ ﻣـﯘﻣﻜﯩﻦ‪ .‬ﻣﻪﺯﻛـﯘﺭ ﺋﻪﻧﺪﯨﺰﯨـﺪﻩ‪ ،‬ﺋﻪﮔﻪﺭ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩـﺪﺍ ﻛﻪﻡ ﺩﯦﮕﻪﻧـﺪﻩ ﺑﯩـﺮ ﺩﺍﻧﻪ ﺋﻪﺯﺍ‬
‫ﺑﻮﻟــﺴﺎ ﺭﺍﺳ ـﺘﻨﻰ‪ ،‬ﺋﯘﻧــﺪﺍﻕ ﺑﻮﻟﻤﯩــﺴﺎ ﻳﺎﻟﻐــﺎﻧﻨﻰ ﻗﺎﻳﺘﯘﺭﯨــﺪﯗ‪ .‬ﮬﯧــﺴﺎﺑﺘﺎ‪ ،‬ﻣﻪﻟــﯘﻡ ﺗﯩﺰﻣﻨﯩــﯔ ﻗــﯘﺭﯗﻕ ﻳــﺎﻛﻰ‬
‫ﺋﻪﻣﻪﺳﻠﯧﻜﯩﻨﻰ ﺗﻪﻛﺸﯜﺭﯨﺪﯗ‪.‬‬
‫ﺋﯩﻜﻜﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﺑﻮﻟﺴﺎ‪ ،‬ﻛﯚﺭﺳﻪﺗﻤﻪ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺷﻪﺭﺕ ﻳﻮﻟﻠﯩﻨﯩﺪﯗ‪ ،‬ﺋﻪﮔﻪﺭ ﺗﯩﺰﻣﯩﺪﺍ ﺋﯘﺷﺒﯘ ﺷﻪﺭﺗﻨﻰ‬
‫ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨﺪﯨﻐﺎﻥ ﺋﻪﺯﺍﺩﯨﻦ ﻛﯧﻤﯩﺪﻩ ﺑﯩﺮﺳﻰ ﺑﻮﻟﺴﺎ ﺭﺍﺳﺘﻨﻰ‪ ،‬ﺑﻮﻟﻤﯩﺴﺎ ﻳﺎﻟﻐﺎﻧﻨﻰ ﻛﻪﻟﺘﯜﺭﯨﺪﯗ‪.‬‬
‫ﻣﻪﺳــﯩﻠﻪﻥ‪ :‬ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﻣﯩــﺴﺎﻟﺪﺍ ﺑــﺎﺭﻟﯩﻖ ﺧﯧﺮﯨــﺪﺍﻻﺭﻧﯩﯔ ﺑــﺎﺭﻟﯩﻖ ﺯﺍﻛﺎﺯﻟﯩﺮﯨﻨﯩــﯔ ﺋﯩﭽﯩــﺪﻩ ﻣﻪﮬــﺴﯘﻻﺕ‬
‫ﺗﻪﺭﺗﯩــﭗ ﻧﻮﻣــﯘﺭﻯ )‪ 1 (idProduct‬ﮔﻪ ﺗﻪﯓ ﺑﻮﻟﻐــﺎﻥ ﻣﻪﮬــﺴﯘﻻﺗﻨﯩﯔ ﻣﻪﯞﺟــﯘﺕ ﻳــﺎﻛﻰ ﺋﻪﻣﻪﺳــﻠﯩﻜﻰ‬
‫ﺗﻪﻛﺸﯜﺭﯛﻟﯩﺪﯗ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪70‬‬

‫ﻛﻮﺩ ‪4.44‬‬

‫‪bool result = ‬‬
‫‪    (from c in customers ‬‬
‫‪         from   o in c.Orders ‬‬
‫‪         select o) ‬‬
‫‪    .Any(o => o.IdProduct == 1); ‬‬
‫ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻗﯘﺭﺩﺍ ﻧﻪﺗﯩﺠﯩﻨﻰ ﻗﻪﺳﺘﻪﻥ ﻳﺎﻟﻐﺎﻥ ﭼﯩﻘﺎﺭﺩﯗﻕ‪ ،‬ﭼﯜﻧﻜﻰ ﺗﯩﺰﻣﺎ ﻗﯘﺭﯗﻕ‪//‬‬

‫‪result = Enumerable.Empty<Order>().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<Order>().All(o => o.Quantity > 0); ‬‬
‫‪//false‬‬

‫ﺋﻪﺳــﻜﻪﺭﺗﯩﺶ‪ :‬ﺋﻪﮔﻪﺭ ‪ All‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﻗــﯘﺭﯗﻕ ﺗﯩﺰﻣﯩﻐــﺎ ﺋﯩﺸﻠﯩﺘﯩﻠــﺴﻪ ﻧﻪﺗﯩﺠـﺴﯩﻰ ﺑﯩــﺮﺩﻩﻙ ﺭﺍﺳــﺖ‬


‫ﺑﻮﻟﯩﺪﯗ‪.‬‬

‫‪) Contains‬ﺑﺎﺭﻣﯘ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ(‬


‫ﺑﯧــﺮﯨﻠﮕﻪﻥ ﺋﻪﺯﺍﻧﯩــﯔ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣﯩــﺪﺍ ﺑــﺎﺭ‪ -‬ﻳــﻮﻗﻠﯩﻘﯩﻨﻰ ﺗﻪﻛــﺸﯜﺭﯨﺪﯗ‪ .‬ﺑــﺎﺭ ﺑﻮﻟــﺴﺎ ﺭﺍﺳــﺘﻨﻰ‪ ،‬ﺑﻮﻟﻤﯩــﺴﺎ‬
‫ﻳﺎﻟﻐﺎﻧﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ‪ .‬ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪71‬‬

‫‪public static bool Contains<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    T value); ‬‬
‫‪public static bool Contains<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    T value, ‬‬
‫)‪    IEqualityComparer<T> comparer‬‬

‫ﺋﻪﮔﻪﺭ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ >‪ ICollection<T‬ﺋﯧﻐﯩﺰﯨﻨﻰ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ ﺑﻮﻟـﺴﺎ‪ Linq ،‬ﺋﺎﻣـﺎﻝ‬
‫ﺑﺎﺭ ﺋﯘﺷﺒﯘ ﺋﯧﻐﯩﺰﻧﻰ ﺋﯩﺸﻠﯩﺘﯩﺪﯗ‪ .‬ﭼﯜﻧﻜﻰ ﺑﯘﻧﺪﺍﻕ ﺑﻮﻟﻐﺎﻧﺪﺍ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺵ ﺑﯩﺮﻗﻪﺩﻩﺭ ﺗﯧﺰ ﺑﻮﻟﯩﺪﯗ‪.‬‬
‫ﺋﻪﮔﻪﺭ ﺋﻪﻣﻪﻟــﮕﻪ ﺋﺎﺷــﯘﺭﻣﯩﻐﺎﻥ ﺑﻮﻟــﺴﺎ‪ ،‬ﻧﯩــﺸﺎﻥ ﺋﻪﺯﺍ ﺑﯩــﻠﻪﻥ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ ﺑﯩﺮﻣــﯘ‪ -‬ﺑﯩــﺮ‬
‫ﺳﯧﻠﯩــﺸﺘﯘﺭﯨﻠﯩﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﺋﯩﻜﻜﯩﻨﭽــﻰ ﺋﻪﻧــﺪﯨﺰﻩ ﺑــﻮﻳﯩﭽﻪ ﺷﻪﺧــﺴﻰ ﺳﯧﻠﯩــﺸﺘﯘﺭﻏﯘﭼﻨﻰ ﻳــﻮﻟﻼﭖ ﺑﻪﺭﺳــﻪ‪،‬‬
‫ﺷﯘﻧﻰ ﺋﯩﺸﻠﯩﺘﯩﺪﯗ‪ .‬ﺋﯘﻧـﺪﺍﻕ ﺑﻮﻟﻤﯩـﺴﺎ ﻛﯚﯕﯜﻟـﺪﯨﻜﻰ ﻗﯩﻤـﻤﻪﺕ ﺑـﻮﻳﯩﭽﻪ ‪ EqualityComparer<T>.‬ﻧـﻰ‬
‫ﺋﯩﺸﻠﯩﺘﯩﺪﯗ‪.‬‬
‫ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻣﯩﺴﺎﻟﺪﺍ ﺗـﯘﻧﺠﻰ ﺧﯧﺮﯨـﺪﺍﺭﻧﯩﯔ ﺯﺍﻛـﺎﺯﻟﯩﺮﻯ ﺋﯩﭽﯩـﺪﻩ ﺑﯧـﺮﯨﻠﮕﻪﻥ ﺯﺍﻛﺎﺯﻧﯩـﯔ ﺑـﺎﺭ‪ -‬ﻳـﻮﻗﻠﯩﻘﻰ‬
‫ﺗﻪﻛﺸﯜﺭﯛﻟﺪﻯ‪:‬‬
‫‪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‬ﺋﻪﺯﺍﻧﻰ ﻳﺎﻛﻰ ﺑﯧﺮﯨﻠﮕﻪﻥ ﺷﻪﺭﺗﻨﻰ ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨﺪﯨﻐﺎﻥ ﺋﺎﻟﺪﯨﻨﻘﻰ ﻣﺎﻧﭽﻪ ﺋﻪﺯﺍﻧﻰ‬
‫ﺋﺎﺗﻼﭖ ﺋﯚﺗﯜﭖ ﻛﯧﺘﯩﺪﯗ‪.‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪72‬‬

‫‪) Take‬ﻧﻰ‪ -‬ﺋﯧﻠﯩﺶ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ(‬


‫ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺋﻪﻧﺪﯨﺰﯨﮕﻪ ﻗﺎﺭﺍﯓ‪:‬‬
‫‪public static IEnumerable<T> Take<T>( ‬‬
‫‪    this IEnumerable<T> 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‬ﺩﯦﮕﻪﻧﮕﻪ ﺳﺎﻗﻼﭖ ﺗﯘﺭﺩﯗﻕ‪.‬‬


‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪73‬‬

‫‪) TakeWhile‬ﭼﺎﻏﺪﺍ‪ -‬ﺋﯧﻠﯩﺶ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ(‬


‫ﺋﯩﺸﻠﯩﺘﯩﺶ ﺋﯘﺳﯘﻟﻰ ‪ Take‬ﺑﯩـﻠﻪﻥ ﺋﻮﺧﺸﯩـﺸﯩﭗ ﻛﯧﺘﯩـﺪﯨﻐﺎﻥ ﺑﻮﻟـﯘﭖ‪ ،‬ﺑﯘﻧﯩﯖـﺪﺍ ﺋﺎﻟـﺪﯨﻨﻘﻰ ﻣﺎﻧﭽﯩـﺴﯩﻨﻰ‬
‫ﺋﻪﻣﻪﺱ‪ ،‬ﺑﻪﻟﻜﻰ ﺋﺎﻟﺪﯨﻨﻘﻰ ﺋﻪﺯﺍﻻﺭﻧﻰ ﺗـﺎﻛﻰ ﺷـﻪﺭﺕ ﻗﺎﻧـﺎﺋﻪﺗﻠﻪﻧﻤﯩﮕﯩﭽﻪ ﺋﺎﻟﯩـﺪﯗ‪ .‬ﺗﯚﯞﻩﻧـﺪﯨﻜﯩﻠﻪﺭ ﺋﯘﻧﯩـﯔ‬
‫ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ‪:‬‬
‫‪public static IEnumerable<T> TakeWhile<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, bool> predicate); ‬‬
‫‪public static IEnumerable<T> TakeWhile<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫;)‪    Func<T, int, bool> 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 ‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 74

     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<T> Skip<T>( 
    this IEnumerable<T> source, 
    int count); 
public static IEnumerable<T> SkipWhile<T>( 
    this IEnumerable<T> source, 
    Func<T, bool> predicate); 
public static IEnumerable<T> SkipWhile<T>( 
    this IEnumerable<T> source, 
    Func<T, int, bool> predicate);

.‫ ﻧﯩﯔ ﺗﻮﻟﯘﻗﻠﯩﻐـﯘﭼﯩﻠﺮﻯ ﺩﻩﭖ ﺋﯧﻴﺘﻘﺎﻧﯩـﺪﯗﻕ‬TakeWhile ‫ ﺑﯩﻠﻪﻥ‬Take ‫ﻳﺎﻳﺎﻡ ﺗﯧﺨﻰ ﺑﯘ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ‬


:‫ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻛﻮﺩ ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ﺗﻮﻟﯘﻕ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ‬،‫ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ‬
var result = customers.Take(3).Union(customers.Skip(3)); 
var result = 
customers.TakeWhile(p).Union(customers.SkipWhile(p)); 
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪75‬‬

‫ﺋﯧﻠﯧﻤﯧﻨﺖ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ‬

‫ﺋﯧﻠﯧﻤﯧﻨــﺖ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺗﯩﺰﻣــﺎ ﺋﯩﭽﯩــﺪﯨﻜﻰ ﻣﻪﻟــﯘﻡ ﺑﯩــﺮﻻ ﺋﻪﺯﺍﻏــﺎ ﺋﺎﻻﻗﯩﻠــﺪﺍﺭ ﻣﻪﺷــﻐﯘﻻﺗﻨﻰ ﺋﯧﻠﯩــﭗ‬
‫ﺑﺎﺭﯨــﺪﯨﻐﺎﻥ ﺑﻮﻟــﯘﭖ‪ ،‬ﻣﻪﻟــﯘﻡ ﺋﻮﺭﯗﻧــﺪﯨﻜﻰ ﻳــﺎﻛﻰ ﺷــﻪﺭﺗﻜﻪ ﺋﯘﻳﻐــﯘﻥ ﺑﯩــﺮﻻ ﺋﻪﺯﺍﻧــﻰ ﻗﺎﻳﺘﯘﺭﯨــﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ‬
‫ﺗﺎﭘﺎﻟﻤﯩﺴﺎ ﻛﯚﯕﯜﻟﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺕ ﺋﻪﺯﺍﺳﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ‪.‬‬

‫‪) First‬ﺗﯘﻧﺠﻰ ﻣﻪﺷﻐﯘﻻﺗﯩﭽﯩﺴﻰ(‬


‫‪ First‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﺗــﯘﻧﺠﻰ ﻳــﺎﻛﻰ )ﺋﻪﮔﻪﺭ ﻛﯚﺭﺳــﻪﺗﻤﻪ ﺷــﻪﺭﺗﻰ ﺑﯧﺮﯨﻠــﺴﻪ( ﺷــﻪﺭﺗﻨﻰ‬
‫ﻗﺎﻧﻪﺋﻪﺗﻠﻪﻧﺪﯛﺭﯨﺪﯨﻐﺎﻥ ﯞﻩ ﻳﺎﻛﻰ ﺋﻮﺭﯗﻥ ﻗﺎﺋﯩﺪﯨﺴﯩﮕﻪ ﭼﯜﺷﯩﺪﯨﻐﺎﻥ ﺗﯘﻧﺠﻰ ﺋﻪﺯﺍﻧﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ‪:‬‬
‫‪public static T First<T>( ‬‬
‫‪    this IEnumerable<T> source); ‬‬
‫‪public static T First<T>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, bool> predicate); ‬‬

‫ﺑﯩﺮﯨﻨﭽﻰ ﺧﯩﻞ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﻩ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﻨﯩﯔ ﺑﯩﺮﯨﻨﭽﻰ ﺋﯧﻠﯧﻤﯧﻨﺘﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨـﺪﯗ‪ .‬ﺋﯩﻜﻜﯩﻨﭽـﻰ ﺧﯩﻠﯩـﺪﺍ‬
‫ﺑﯧــﺮﯨﻠﮕﻪﻥ ﺷــﻪﺭﺗﻜﻪ ﭼﯜﺷــﯩﺪﯨﻐﺎﻥ ﺗــﯘﻧﺠﻰ ﺋﯧﻠﯧﻤﯧﻨﺘﻨــﻰ ﻗﺎﻳﺘﯘﺭﯨــﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﺷــﻪﺭﺗﻜﻪ ﭼﯜﺷــﯩﺪﯨﻐﺎﻥ‬
‫ﺋﯧﻠﯧﻤﯧﻨﺖ ﺗﯧﭙﯩﻠﻤﯩﺴﺎ ﻳﺎﻛﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﺎ ﻗـﯘﺭﯗﻕ ﺑﻮﻟـﺴﺎ‪ ،‬ﻣﻪﺷـﻐﯘﻻﺗﭽﻰ ‪InvalidOperationException‬‬
‫ﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﻗﻮﻳﯘﭖ ﺑﯧﺮﯨﺪﯗ‪ .‬ﺗﯚﯞﻩﻧﺪﻩ ﺑﯩﺮﻣﯩﺴﺎﻝ‪:‬‬
‫ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ ‪ USA‬ﺑﻮﻟﻐﺎﻥ ﺗﯘﻧﺠﻰ ﺧﯧﺮﯨﺪﺍﺭﻏﺎ ﺋﯧﺮﯨﺸﯩﺶ‬ ‫ﻛﻮﺩ ‪4.49‬‬

‫‪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‬ﺋﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ‪ .‬ﺗﯚﯞﻩﻧﺪﻩ ﺑﯩﺮ ﻣﯩﺴﺎﻝ‪:‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 76

4.50 ‫ﻛﻮﺩ‬

var item = customers.FirstOrDefault(c => c.City == "Las Vegas"); 
Console.WriteLine(item == null ? "null" : item.ToString()); // null 
 
IEnumerable<Customer> emptyCustomers = 
Enumerable.Empty<Customer>(); 
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<T>( 
    this IEnumerable<T> source); 
public static T Last<T>( 
    this IEnumerable<T> source, 
    Func<T, bool> predicate); 
public static T LastOrDefault<T>( 
    this IEnumerable<T> source); 
public static T LastOrDefault<T>( 
    this IEnumerable<T> source, 
    Func<T, bool> predicate);

Single
‫ ﺗﯩﺰﻣﯩﻼﺭﻧﯩـﯔ ﯞﻩﻛﯩﻠـﻰ ﺳـﯜﭘﯩﺘﯩﺪﻩ( ﺋﺎﻟﻤـﺎﻗﭽﻰ‬:‫ﺋﻪﮔﻪﺭ ﺗﯩﺰﻣﯩﺪﯨﻦ ﺑﯩﺮﺗﺎﻝ ﺋﻪﺯﺍﻧﻰ ﺷـﯘﻧﺪﺍﻗﻼ )ﻣﻪﺳـﯩﻠﻪﻥ‬
:‫ ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‬.‫ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﯔ‬Single ‫ﺑﻮﻟﺴﯩﯖﯩﺰ‬
public static T Single<T>( 
    this IEnumerable<T> source); 
public static T Single<T>( 
    this IEnumerable<T> source, 
    Func<T, bool> predicate);
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪77‬‬

‫ﺋﻪﮔﻪﺭ ﻛﯚﺭﺳﻪﺗﻜﯜﭺ ﺷﻪﺭﺗﻰ ﺑﯧﺮﯨﻠﻤﯩﺴﻪ‪ ،‬ﻗﺎﻳﺘﯩﺪﯨﻐﯩﻨﻰ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺑﯩﺮﯨﻨﭽﻰ ﺋﯧﻠﯧﻤﯧﻨﺖ ﺑﻮﻟﯩﺪﯗ‪ .‬ﺋﯘﻧﺪﺍﻕ‬
‫ﺑﻮﻟﻤﯩﻐﺎﻧﺪﺍ ﺷﻪﺭﺗﻜﻪ ﭼﯜﺷﯩﺪﯨﻐﺎﻥ ﺑﯩﺮﺗﺎﻝ ﺋﯧﻠﯧﻤﯧﻨﺖ ﺑﻮﻟﯩﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﻛﯚﺭﺳﻪﺗﻜﯜﭺ ﺑﻮﻟﻤﯩﺴﺎ ﮬﻪﻣﺪﻩ ﺗﯩﺰﻣﯩﺪﺍ‬
‫ﺑﯩﺮﺩﯨﻦ ﺋﺎﺭﺗﯘﻕ ﺋﯧﻠﯧﻤﻨﺖ ﺑﻮﻟﺴﺎ ‪ 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<Product> emptyProducts = Enumerable.Empty<Product>(); ‬‬
‫‪item = emptyProducts.Single(p => p.IdProduct == 1); ‬‬
‫‪Console.WriteLine(item == null ? "null" : item.ToString()); ‬‬

‫‪SingleOrDefault‬‬
‫‪ SingleOrDefault‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﻗﯘﺭﯗﻕ ﻳـﺎﻛﻰ ﺷـﻪﺭﺗﻜﻪ ﺋﯘﻳﻐـﯘﻥ ﺋﯧﻠﯧﻤﯧﻨـﺖ ﺑﻮﻟﻤﯩﻐـﺎﻥ ﺗﯩﺰﻣﯩـﺪﯨﻦ‬
‫ﻛﯚﯕﯜﻟـــﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗﻨـــﻰ ﻗﺎﻳﺘﯘﺭﯨـــﺪﯗ‪ .‬ﺑـــﯘ ﻳﻪﺭﺩﯨﻜـــﻰ »ﻛﯚﯕﯜﻟـــﺪﯨﻜﻰ ﻗﯩﻤـــﻤﻪﺕ« ‪FirstOrDefault‬‬
‫ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﺪﺍ ﺳﯚﺯﻟﻪﻧﮕﯩﻨﻰ ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ ﺑﯩﻠﻪﻥ ﺋﻮﺧﺸﺎﺵ‪.‬‬
‫ﺋﻪﺳﻜﻪﺭﺗﯩﺶ‪ default :‬ﻗﯩﻤﻤﻪﺕ ﭘﻪﻗﻪﺕ ﺷﻪﺭﺗﻜﻪ ﺋﯘﻳﻐـﯘﻥ ﺋﯧﻠﯧﻤﯧﻨـﺖ ﺗﯧﭙﯩﻠﻤﯩﻐﺎﻧـﺪﯨﻼ ﻗﺎﻳﺘﯩـﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ‬
‫ﺗﯩﺰﻣﯩـــﺪﺍ ﺷـــﻪﺭﺗﻜﻪ ﺋﯘﻳﻐـــﯘﻥ ﺑﯩـــﺮﺩﯨﻦ ﺋــــﺎﺭﺗﯘﻕ ﺋﯧﻠﻤﯧﻨﯧﻨـــﺖ ﺑﻮﻟـــﯘﭖ ﻗﺎﻟـــﺴﺎﻕ ﻣﻪﺷــــﻐﯘﻻﺗﯩﭽﻰ‬
‫‪ InvalidOperationException‬ﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨﺪﯗ‪.‬‬

‫‪ ElementAt‬ﺑﯩﻠﻪﻥ ‪ElementAtOrDefault‬‬
‫‪ ElementsAt‬ﺑﯩـــﻠﻪﻥ ‪ ElementAtOrDefault‬ﺗﯩﺰﻣﯩﻨﯩـــﯔ ﺑﻪﻟﮕﯩﻠﻪﻧـــﮕﻪﻥ ﺋﻮﺭﯗﻧـــﺪﯨﻜﻰ ﺋﯧﻠﯧﻤﯧﻨﺘﻨـــﻰ‬
‫ﺋﯧﻠﯩﺶ ﺋﯜﭼﯜﻥ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪:‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 78

public static T ElementAt<T>( 
    this IEnumerable<T> source, 
    int index); 
public static T ElementAtOrDefault<T>( 
    this IEnumerable<T> 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<Product>().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<T> DefaultIfEmpty<T>( 
    this IEnumerable<T> source); 
public static IEnumerable<T> DefaultIfEmpty<T>( 
    this IEnumerable<T> source, 
    T defaultValue);
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪79‬‬

‫ﺑﻪﻟﮕﯩﻠﯩﻤﯩﺴﻰ ﺑﻮﻳﯩﭽﻪ‪ ،‬ﺋﯘ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ ﺗـﻮﭘﯩﻨﻰ ﻗﺎﻳﺘﯘﺭﯨـﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣـﺎ ﻗـﯘﺭﯗﻕ‬
‫ﺑﻮﻟﺴﺎ‪ ،‬ﺑﯩﺮﯨﻨﭽﻰ ﺋﻪﻧﺪﯨﺰﯨﺪﻩ )‪ 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<Order>(Enumerable.Empty<Order>())).ToArray(); ‬‬
‫‪       return(empty); ‬‬
‫‪    } ‬‬
‫}‬

‫ﺑﻪﺯﯨﺪﻩ ﺑﯘﻧـﺪﺍﻕ ﻗﯩﻠﯩـﺶ ﻳﺎﺧـﺸﻰ ﺋﯩـﺶ‪ ،‬ﺑﻮﻟﯘﭘﻤـﯘ ﺑـﯚﻟﻪﻙ ﺳـﯩﻨﯩﻘﻰ ﺋﯧﻠﯩـﭗ ﺑﺎﺭﻏﺎﻧـﺪﺍ ﺋﯩﻨﺘـﺎﻳﯩﻦ ﺋﻪﺱ‬
‫ﻗﺎﺗﯩﺪﯗ‪ .‬ﺋﯘﻧﯩﯖﺪﯨﻦ ﺑﺎﺷﻘﺎ‪ ،‬ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ‪ GroupJoin‬ﻧـﻰ ﺋﯩـﺸﻠﯩﺘﯩﭗ ﺳـﻮﻝ‪ -‬ﺳـﯩﺮﺗﻘﻰ ﮬﻪﻣـﺪﻩﻣﯩﻨﻰ‬
‫ﺑﺎﻳﻘﯩﻐﺎﻧﺪﺍ‪ Null ،‬ﺑﻮﻟﯘﺵ ﺋﯧﮫﺘﯩﻤﺎﻟﻠﯩﻘﻰ ﺑﻮﻟﻐﺎﻥ ﻧﻪﺗﯩﺠﯩﻨﻰ ﻛﯚﯕﯜﻟـﺪﯨﻜﻰ ﻗﯩﻤﻤﻪﺗـﻜﻪ ﺋﺎﻳﻼﻧـﺪﯗﺭﯗﯞﯦﺘﯩﺶ‬
‫ﻳﺎﺧﺸﻰ ﺋﺎﺩﻩﺕ‪.‬‬
‫ﺗﯚﯞﻩﻧﺪﻩ ‪ DefaultEmpty‬ﻧﻰ ﺋﯩﺸﻠﯩﺘﯩﺸﺘﯩﻦ ﺑﯩﺮ ﻣﯩﺴﺎﻝ‪:‬‬
‫ﻛﻮﺩ ‪4.53‬‬

‫‪var expr = customers.DefaultIfEmpty(); ‬‬
‫‪ ‬‬
‫‪var customers = Enumerable.Empty<Customer>(); // Empty array ‬‬
‫‪IEnumerable<Customer> customersEmpty = ‬‬
‫‪    customers.DefaultIfEmpty(Customer.Empty); ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪80‬‬

‫ﺑﺎﺷﻘﺎ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ‬
‫‪ Concat‬ﺑﯩﻠﻪﻥ ‪ SequanceEqual‬ﻣﻪﺯﻛﯘﺭ ﭘﺎﺭﺍﮔﺮﺍﻓﺘﯩﻜﻰ ﺋﻪﯓ ﺋﺎﺧﯩﺮﯨﻘﻰ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭ‪.‬‬

‫‪) Concat‬ﺋﯘﻻﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ(‬


‫‪ Concat‬ﺑﯩــﺮ ﺗﯩﺰﻣﯩﻨــﻰ ﻳﻪﻧﻪ ﺑﯩــﺮ ﺗﯩﺰﻣﯩﻐــﺎ ﺋــﯘﻻﺵ ﺋﯧﻠﯩــﭗ ﺑﺎﺭﯨــﺪﯨﻐﺎﻥ ﺑﻮﻟــﯘﭖ ﺋﯘﻧﯩــﯔ ﺋﻪﻧــﺪﯨﺰﯨﻠﯩﺮﻯ‬
‫ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫‪public static IEnumerable<T> Concat<T>( ‬‬
‫‪    this IEnumerable<T> first, ‬‬
‫;)‪    IEnumerable<T> second‬‬

‫ﻛﯚﺭﯨﯟﯦﻠﯩﺸﻘﺎ ﺑﻮﻟﯩﺪﯗ‪ Concat ،‬ﺋﺎﺭﻗﯩﻠﯩﻖ >‪ IEnumerable<T‬ﺗﯩﭙﻠﯩﻖ ﺧﺎﻟﯩﻐﺎ ﺋﯩﻜﻜﻰ ﺩﺍﻧﻪ ﺗﯩﺰﻣﯩﻨﻰ ﺑﯩﺮ‬
‫ﺑﯩﺮﯨﮕﻪ ﺋﯘﻟﯩﻴﺎﻻﻳﻤﯩﺰ‪.‬‬
‫ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻣﯩﺴﺎﻟﺪﺍ‪ ،‬ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ ‪ Italy‬ﺑﻮﻟﻐﺎﻥ ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ ‪USA‬‬
‫ﺑﻮﻟﻐﺎﻥ ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﺗﯩﺰﻣﯩﺴﯩﻐﺎ ﺋﯘﻻﺵ ﺋﯧﻠﯩﭗ ﺑﺎﺭﯨﺪﯗ‪:‬‬
‫ﻛﻮﺩ ‪4.54‬‬

‫‪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); ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪81‬‬

‫‪SequenceEqual‬‬
‫ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﻳﻪﻧﻪ ﺑﯩــﺮ ﻗﻮﻟﻠﯩﻨﯩــﺸﭽﺎﻥ ﻣﻪﺷــﻐﯘﻻﺗﭽﻰ ﺑﻮﻟــﯘﭖ‪SequenceEqual ،‬‬
‫ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﯗﻟﻐﺎﻥ‪:‬‬
‫‪public static bool SequenceEqual<T>( ‬‬
‫‪    this IEnumerable<T> first, ‬‬
‫‪    IEnumerable<T> second); ‬‬
‫‪public static bool SequenceEqual<T>( ‬‬
‫‪    this IEnumerable<T> first, ‬‬
‫‪    IEnumerable<T> second, ‬‬
‫;)‪    IEqualityComparer<T> comparer‬‬

‫ﺳﯧﻠﯩﺸﺘﯘﺭﯗﺵ ﺟﻪﺭﻳﺎﻧﯩﺪﺍ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﮬﻪﺭﺑﯩﺮ ﺋﻪﺯﺍ ﻧﯩﺸﺎﻥ ﺗﯩﺰﻣﯩـﺪﯨﻜﻰ ﺋـﯚﺯﻯ ﺑﯩـﻠﻪﻥ ﺋﻮﺧـﺸﺎﺵ‬
‫ﺋﻮﺭﯗﻧﺪﯨﻜﻰ ﺋﻪﺯﺍ ﺑﯩﻠﻪﻥ ﺳﯧﻠﯩﺸﺘﯘﺭﯗﻟﯘﭖ ﭼﯩﻘﯩﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﺋﯩﻜﻜـﻰ ﺗﯩﺰﻣﯩﻨﯩـﯔ ﺑـﺎﺭﻟﯩﻖ ﺋﻪﺯﺍﻟﯧـﺮﻯ ﺋـﻮﺭﯗﻥ‬
‫ﺟﻪﮬﻪﺗــﺘﯩﻦ ﯞﻩ ﺳــﺎﻥ ﺟﻪﮬﻪﺗــﺘﯩﻦ ﺋﻮﺧــﺸﺎﺵ ﭼﯩﻘــﺴﺎ ﺋﺎﻧــﺪﯨﻦ ﺭﺍﺳــﺖ ﻗﺎﻳﺘﯩــﺪﯗ‪ ،‬ﺧﺎﻟﯩﻐــﺎﻥ ﺑﯩﺮﺳــﻰ‬
‫ﻗﺎﻧﺎﺋﻪﺗﻠﻪﻧﻤﯩــﺴﻪ ﻳﺎﻟﻐــﺎﻥ ﻗﺎﻳﺘﯩــﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﺗﯩﺰﻣﯩــﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ ﭼﺎﻗﯩﺮﯨﻠﻤــﺎ ﺗﯩﭙﻠﯩــﻖ ﺑﻮﻟــﺴﺎ‪ ،‬ﺋﯘﻧﯩــﯔ‬
‫ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﻟﯘﻕ ﺧــﯘﻟﻘﯩﻨﻰ ﻗــﻮﻝ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﯚﮔﻪﺭﺗﯩــﺸﯩﯖﯩﺰ ﻛﯧــﺮﻩﻙ‪ .‬ﻳــﺎﻛﻰ ﺋﯩﻜﻜﯩﻨﭽــﻰ ﺧﯩـﻞ ﺋﻪﻧــﺪﯨﺰﻩ‬
‫ﺋﺎﺭﻗﯩﻠﯩﻖ ﺧﺎﺳﻼﺷﺘﯘﺭﯗﻟﻐﺎﻥ ﺳﯧﻠﯩﺸﺘﯘﺭﻏﯘﭺ ﺑﯩﻠﻪﻥ ﺗﻪﻣﯩﻨﻠﯩﺴﯩﯖﯩﺰﻣﯘ ﺑﻮﻟﯩـﺪﯗ‪) .‬ﺑـﯘ ﺗﻮﻏﺮﯨﻠﯩـﻖ ﺋﺎﻟـﺪﯨﻨﻘﻰ‬
‫ﻣﻪﺯﻣﯘﻧﻼﺭﺩﺍ ﺗﻮﺧﺘﺎﻟﻐﺎﻥ(‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪82‬‬

‫ﻛﯧﭽﯩﻜﺘﯜﺭﯛﻟﻤﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻨﯩﺸﻰ ﯞﻩ ﻛﯧﯖﻪﻳـﺘﯩﻠﻤﻪ ﻣﯧﺘـﻮﺩ‬

‫ﭼﺎﺭﯨﺴﻰ‬
‫]‪[Deferred Query Evaluation and Extension Methods Resolution, 延迟的查询赋值与扩展方法‬‬

‫ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷﺨﯘﻻﭼﯩﻠﯩﺮﻯ )ﻣﯘﺷﯘ ﭘﺎﺭﺍﮔﺮﺍﻓﻨﯩﯔ ﺋﺎﺧﯩﺮﯨﺪﺍ ﺳﯚﺯﻟﯩﻨﯩﺪﯗ( ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﻧﻪﺗﯩﺠﯩـﺴﯩﻨﻰ‬


‫ﺋﻮﺧﺸﯩﻤﯩﻐﺎﻥ ﺷﻪﻛﻜﯩﻠﻠﻪﺭﺩﻩ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﺍﻻﻳﺪﯗ‪ .‬ﺑﯘ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻼﺭﻏﺎ ﺑﻮﻟﻐﺎﻥ ﺋﯧﮫﺘﯩﻴﺎﺟﻨﻰ ﭼﯜﺷﻪﻧﺪﯛﺭﯛﺵ‬
‫ﺋﯜﭼــﯜﻥ ‪ Linq‬ﻧﯩــﯔ »ﻛﯧﭽﯩﻜﺘــﯜﺭﯛﻟﻤﻪ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻛﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻨﯩــﺸﻰ« ﯞﻩ »ﻛﯧﯖﻪﻳــﺘﯩﻠﻤﻪ ﻣﯧﺘــﻮﺩ‬
‫ﭼﺎﺭﯨﺴﻰ« ﻻﺭﺩﯨـﻦ ﺋﯩﺒـﺎﺭﻩﺕ ‪ Linq‬ﻧﯩـﯔ ﺑـﺎﺭﻟﯩﻖ ﺋﻪﻣﻪﻟـﮕﻪ ﺋﺎﺷـﯘﺭﯗﻟﻤﯩﻠﯩﺮﻯ ﺋﯜﭼـﯜﻥ ﺋﯩﻨﺘـﺎﻳﯩﻦ ﻣـﯘﮬﯩﻢ‬
‫ﺑﻮﻟﻐﺎﻥ ﺋﯩﻜﻜﻰ ﺧـﯘﻟﻘﯩﻨﻰ ﺑﺎﻳـﺎﻥ ﻗﯩﻠﯩـﺶ ﺯﯙﺭﯛﺭ‪ .‬ﺷـﯘﯕﺎ ﻣﻪﺯﻛـﯘﺭ ﭘـﺎﺭﺍﮔﺮﺍﻓﻨﻰ ﺗﯧﺨﯩﻤـﯘ ﺋﻪﺳـﺘﺎﻳﯩﺪﯨﻠﻠﯩﻖ‬
‫ﺑﯩﻠﻪﻥ ﻛﯚﺭﯛﺷﯩﯖﯩﺰﻧﻰ ﺋﯜﻣﯩﺪ ﻗﯩﻠﯩﻤﻪﻥ‪.‬‬

‫ﻛﯧﭽﯩﻜﺘﯜﺭﯛﻟﻤﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻨﯩﺸﻰ‬


‫‪ Linq‬ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻛﻠﯩﺮﻯ ﺋﯧﻨﯩﻘﻼﻧﻐﺎﻧــﺪﺍ ﺋﻪﻣﻪﺱ ﺑﻪﻟﻜــﻰ ﺋﯩــﺸﻠﯩﺘﯩﻠﮕﻪﻧﺪﯨﻼ ﺋﺎﻧــﺪﯨﻦ ﺋﯩﺠــﺮﺍ ﺑﻮﻟﯩــﺪﯗ‪.‬‬
‫ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﮕﻪ ﻗﺎﺭﺍﯓ‪:‬‬
‫‪List<Customer> customersList = new List<Customer>(customers); ‬‬
‫‪ ‬‬
‫‪var expr = ‬‬
‫‪    from   c in customersList ‬‬
‫‪    where  c.Country == Countries.Italy ‬‬
‫;‪    select c‬‬

‫ﻳﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩ ﺩﯙﻟﻪﺕ ﺗﻪﯞﻩﻟﯩﻜﻰ ‪ Italy‬ﺑﻮﻟﻐﺎﻥ ﺧﯧﺮﯨﺪﺍﺭﻻﺭ ﺗﯩﺰﻣﯩﺴﯩﻐﺎ ﺋﯧﺮﯨﺸﯩﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ‬

‫;))(‪Console.WriteLine("\nItems after query definition: {0}", expr.Count‬‬

‫ﻧﻰ ﺋﯩﺠﺮﺍ ﻗﯩﻠﺴﺎﻕ‪ ،‬ﺑﯩﺰﻧﯩﯔ ﺑﯘﺭﯗﻥ ﺑﯧﻜﯩﺘﯩﯟﺍﻟﻐﺎﻥ ﻣﯩـﺴﺎﻝ ﺋﯘﭼﯘﺭﻟﯩﺮﯨﻤﯩﺰﻏـﺎ ﺋﺎﺳﺎﺳـﻪﻥ‪،‬ﻧﻪﺗﯩﺠﻪ ﺋﯩﻜﻜـﻰ‬
‫ﭼﯩﻘﯩﺪﯗ‪ ،‬ﻳﻪﻧﻰ ﺋﯩﭙﺎﺩﯨﺪﯨﻜﻰ ﺷﻪﺭﺗﻜﻪ ﭼﯜﺷﯩﺪﯨﻐﺎﻥ ﺋﯩﻜﻜﻰ ﺧﯧﺮﯨﺪﺍﺭ ﺑﺎﺭ‪ .‬ﺋﻪﻣﺪﻯ ﻳﯧﯖـﻰ ﺧﯧﺮﯨـﺪﺍﺭﻻﺭﻧﻰ‬
‫ﻗﻮﺷﯘﺵ ﺋﺎﺭﻗﯩﻠﯩﻖ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﻨﻰ ﺋﯚﺯﮔﻪﺭﺗﻪﻳﻠﻰ )ﻳﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩﯨﻨﯩﯔ ﻛﻪﻳﻨﯩﺪﯨﻨﻼ(‪:‬‬
‫‪customersList.Add( ‬‬
‫‪  new Customer {Name = "Roberto", City = "Firenze", ‬‬
‫‪    Country = Countries.Italy, Orders = new Order[] { ‬‬
‫‪    new Order {Quantity = 3, IdProduct = 1 , Shipped = false, ‬‬
‫‪      Month = "March"}}}); ‬‬

‫ﺋﻪﻣﺪﻯ ﻧﻪﺗﯩﺠﻪ ﺗﯩﺰﻣﯩﺴﻰ ‪ expr‬ﻧﯩﯔ ﭼﺎﺭﻟﯩﺴﺎﻕ ﻳﺎﻛﻰ ﺋﯘﻧﯩﯖﺪﯨﻜﻰ ﺋﻪﺯﺍ ﺳﺎﻧﯩﻨﻰ ﺗﻪﻛﺸﯜﺭﺳﻪﻙ‪ ،‬ﻧﻪﺗﯩﺠﻪ‬
‫ﺋﺎﻟﺪﯨﻨﻘﻰ ﻗﯧﺘﯩﻤﺪﯨﻜﯩﺪﻩﻙ ﭼﯩﻘﻤﺎﻳﺪﯗ )ﺋﺎﻟﺪﯨﻨﻘﻰ ﻗﯧﺘﯩﻢ ﺋﯩﻜﻜﻰ ﺋﯩﺪﻯ(‪ .‬ﻳﻪﻧﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻛﻮﺩﯨﻨﻰ ﺋﯩﺠﺮﺍ‬
‫ﻗﯩﻠﯩﭗ ﻛﯚﺭﺳﻪﻙ‪:‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪83‬‬

‫ﻛﻮﺩ ‪4.55‬‬

‫‪Console.WriteLine("\nItems after source sequence modification: ‬‬
‫‪{0}", expr.Count()); ‬‬
‫‪ ‬‬
‫‪foreach (var item in expr) { ‬‬
‫‪    Console.WriteLine(item); ‬‬
‫‪} ‬‬

‫ﻧﻪﺗﯩـــﺠﻪ ﺗﯚﯞﻩﻧﺪﯨﻜﯩـــﺪﻩﻙ ﭼﯩﻘﯩـــﺪﯗ‪ .‬ﺩﯨﻘـــﻘﻪﺕ ﻗﯩﻠﯩـــﯔ‪ ،‬ﮔﻪﺭﭼﻪ ‪ Roberto‬ﺋﯩـــﺴﯩﻤﻠﯩﻚ ﺧﯧﺮﯨـــﺪﺍﺭ‬


‫ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨــﺴﯩﻨﻰ ﺋﯧــﻨﯩﻘﻼﭖ )ﻳﯧﺰﯨــﭗ( ﺑﻮﻟﻐﺎﻧــﺪﯨﻦ ﻛﯧــﻴﯩﻦ ﻗﻮﺷــﯘﻟﻐﺎﻥ ﺑﻮﻟــﺴﯩﻤﯘ‪ ،‬ﻟــﯧﻜﯩﻦ‬
‫ﻧﻪﺗﯩﺠﯩﺪﻩ ﻳﻪﻧﯩﻼ ﺑﺎﺭ‪.‬‬
‫‪Items after source sequence modification: 3‬‬
‫‪Paolo - Brescia – Italy‬‬
‫‪Marco - Torino – Italy‬‬
‫‪Roberto - Firenze - Italy‬‬

‫ﺋﻪﺳﻜﻪﺭﺗﯩﺶ‪ Linq :‬ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﯩﻨﯩﯔ ﻟﻮﮔﯩﮕﯩﻜﯩﺴﯩﺪﯨﻦ ﻗﺎﺭﯨﻐﺎﻧﺪﺍ‪ ،‬ﺋﯘﻧﯩﯔ ﺋﯩﭙﺎﺩﯨﻠﻪﻳﺪﯨﻐﯩﻨﻰ‬


‫»ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﭘﯩﻼﻧﻰ« ﺧﺎﻻﺱ‪ .‬ﭼﯜﻧﻜﻰ ﺋﯘ ﺗﺎﻛﻰ ﺋﯘﻧﻰ ﺋﯩﺸﻠﻪﺗﻜﯩﭽﻪ ﺋﯩﺠﺮﺍ ﺑﻮﻟﻤﺎﻳﺪﯗ‪ .‬ﮬﻪﺭ ﻗﯧﺘﯩﻢ ﻗﺎﻳﺘﺎ‬
‫ﺋﯩﺸﻠﺘﯩﯩﺶ ﺋﯘﻧﯩﯔ ﻗﺎﻳﺘﺎ ﺋﯩﺠﺮﺍ ﺑﻮﻟﯘﺷﯩﻨﻰ ﻛﻪﻟﺘﯜﺭﯛﭖ ﭼﯩﻘﯩﺮﯨﺪﯗ‪ .‬ﺑﻪﺯﻯ ‪ Linq‬ﻧﯩﯔ ﺋﻪﻣﻪﻟﮕﻪ‬
‫ﺋﺎﺷﯘﺭﻣﯩﻠﯩﺮﻯ‪ ،‬ﻣﻪﺳﯩﻠﻪﻥ‪ ،Linq to Objects :‬ﺋﯘﺷﺒﯘ ﺧﯘﻟﻘﯩﻨﻰ ﻣﯘﯞﻩﻗﻘﻪﺗﻠﻪﺭ)‪ (delegates‬ﺋﺎﺭﻗﯩﻠﯩﻖ‬
‫ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ‪ .‬ﻟﯧﻜﯩﻦ ‪ Linq to Sql‬ﺑﻮﻟﺴﺎ ﺋﯘﻧﻰ ﺋﯩﭙﺎﺩﻩ ﺩﻩﺭﯨﺨﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﻣﻪﻟﮕﻪ ﺋﺎﺷﯘﺭﻏﺎﻥ‪.‬‬

‫»ﻛﯧﭽﯩﻜﺘﯜﺭﯛﻟﻤﻪ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻛﻨﯩﯔ ﻗﯩﻤﻤﻪﺗﻠﯩﻨﯩﺸﻰ« ﻧـﻰ ﺑﯩـﺮﻻ ﻗﯧـﺘﯩﻢ ﺋﯧـﻨﯩﻘﻼﭖ ﺗﻪﻛـﺮﺍﺭ ﺋﯩـﺸﻠﻪﺗﻜﯩﻠﻰ‬


‫ﺑﻮﻟﻐﺎﻧﻠﯩﻘﻰ ﺋﯜﭼـﯜﻥ‪ ،‬ﺋـﯘ ﻧﯘﺭﻏـﯘﻥ ﻗـﻮﻻﻳﻠﯩﻘﻼﺭﻧﻰ ﺋﯧﻠﯩـﭗ ﻛﻪﻟـﮕﻪﻥ‪ .‬ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣـﺎ ﻣﻪﺯﻣﯘﻧﯩﻐـﺎ ﻗﺎﻧـﺪﺍﻕ‬
‫ﺋﯚﺯﮔﯩﺮﯨﺸﻠﻪﺭﻧﯩﯔ ﺑﻮﻟﯘﺷﯩﺪﯨﻦ ﻗﻪﺗﺌﯩﻲ ﻧﻪﺯﻩﺭ‪ ،‬ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﻧﻪﺗﺠﯩـﺴﻰ ﮬﺎﻣـﺎﻥ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩﻨﯩـﯔ ﺋﻪﯓ‬
‫ﻳﯧﯖﻰ ﻣﻪﺯﻣﯘﻧﯩﻨﻰ ﺋﺎﺳﺎﺱ ﻗﯩﻠﯩﺪﯗ‪.‬‬
‫ﺑﯩﺮﺍﻕ‪ ،‬ﺑﯘﻧﯩﺴﻰ ﺩﺍﺋﯩـﻢ ﻗﻮﻻﻳﻠﯩـﻖ ﺑﻮﻟﯘﺷـﻰ ﻧﺎﺗـﺎﻳﯩﻦ‪ .‬ﺋﻪﮔﻪﺭ ﺋﻮﺧـﺸﯩﻤﯩﻐﺎﻥ ﭘﻪﻳﺘﺘﯩﻜـﻰ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩﻐـﺎ‬
‫ﺋﺎﻟﻤﺎﺷـﺘﯘﺭﯗﺵ‬ ‫ﻧﯩﺴﺒﻪﺗﻪﻥ ﺳﯜﺭﯛﺷﯜﺗﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﻩ ﻧﻪﺗﯩﺠﯩﺴﯩﻨﻰ ﺳـﺎﻗﻼﭖ ﻗﺎﻟﻤـﺎﻗﭽﻰ ﺑﻮﻟـﺴﯩﯖﯩﺰﭼﯘ؟‪...‬‬
‫ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﻳﺎﺭﺩﻩﻡ ﻗﯩﻠﯩﺪﯗ‪.‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 84

‫ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ ﭼﺎﺭﯨﺴﻰ‬

.‫ ﻧﻰ ﺋﯩﮕﯩﻠﻪﺵ ﺟﻪﺭﻳـﺎﻧﯩﯖﯩﺰﺩﯨﻜﻰ ﺋﻪﯓ ﻣـﯘﮬﯩﻢ ﺋﯘﻗﯘﻣﻼﺭﻧﯩـﯔ ﺑﯩـﺮﻯ‬Linq ‫ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩ ﭼﺎﺭﯨﺴﻰ‬


‫ ﻧــﺎﻣﻠﯩﻖ ﺋﯚﺯﯨﻤﯩﺰﻧﯩــﯔ ﺧﯧﺮﯨــﺪﺍﺭﻻﺭ ﺗﯩﺰﻣــﺎ ﺗﯩﭙﯩﻨــﻰ‬Customers ،‫ ﺋﯘﻧﯩﯖــﺪﺍ‬.‫ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﻛﻮﺩﻗــﺎ ﻗــﺎﺭﺍﯓ‬
‫ ﻧــﻰ ﻛﯧﯖﻪﻳــﺘﯩﻠﮕﻪﻥ ﻣﯧﺘــﻮﺩﻻﺭ ﺑﯩــﻠﻪﻥ ﺗﻪﻣﯩﻨﻠﻪﻳــﺪﯨﻐﺎﻥ‬Customers ‫ ﺋﯘﻧﯩﯖــﺪﯨﻦ ﺑﺎﺷــﻘﺎ‬.‫ﺋﯧﻨﯩﻘﻠﯩــﺪﯗﻕ‬
‫ ﺋﺎﻻﮬﯩــﺪﻩ ﻣﻪﺷــﻐﯘﻻﺕ‬Customers ‫ ﺋﯘﻧﯩــﯔ ﺋﯩﭽﯩــﺪﻩ‬.‫ ﻧــﺎﻣﻠﯩﻖ ﺗــﯜﺭ ﻗــﯘﺭﺩﯗﻕ‬CutomersEnumerable
:‫ ﻧﺎﻣﻠﯩﻖ ﻛﯧﯖﻪﻳﻤﻪ ﻣﯧﺘﻮﺩﻧﻰ ﺋﯧﻨﯩﻘﻠﯩﺪﯗﻕ‬Where ‫ﺋﯧﻠﯩﭗ ﺑﺎﺭﯨﺪﯨﻐﺎﻥ‬
public sealed class Customers: List<Customer> { 
    public Customers(IEnumerable<Customer> items): base(items) {} 

 
public static class CustomersEnumerable { 
    public static IEnumerable<Customer> Where( 
        this Customers source, Func<Customer, bool> predicate) 
{ ... } 
 
    public static IEnumerable<Customer> Where( 
        this Customers source, Func<Customer, int, bool> predicate) 
{ ... } 
}

‫ ﺩﯨﻜﯩـﺪﻩﻙ‬4.56 ‫ ﺗﯩﺰﻣﯩﺴﯩﻨﻰ ﺋﯩﺸﻠﺘﯩﭗ ﻛـﻮﺩ‬customers ‫ﺋﻪﮔﻪﺭ ﺑﺎﺷﺘﯩﻦ ﺑﯧﺮﻯ ﺋﯩﺸﻠﯩﺘﯩﭗ ﻛﯧﻠﯩﯟﺍﺗﻘﺎﻥ‬


:‫ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﻰ ﻳﺎﺯﺳﺎﻕ‬
4.56 ‫ﻛﻮﺩ‬

Customers customersList = new Customers(customers); 
 
var expr = 
    from   c in customersList 
    where  c.City == "Brescia" 
    select c; 
 
foreach (var item in expr) { 
    Console.WriteLine(item); 

‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪85‬‬

‫ﻛﻮﺩ‪-‬ﺗﻪﺭﺟﯩﻤﺎﻥ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﻨﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻛﻮﺩﻗﺎ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯨﺪﯗ‪.‬‬


‫‪var expr = ‬‬
‫‪    customersList ‬‬
‫‪    .Where(c => c.City == "Brescia") ‬‬
‫‪    .Select(c => c); ‬‬

‫ﺑﯩــﺰ ﺑﺎﻳــﺎﻡ ﻗﯘﺭﯨﯟﺍﻟﻐــﺎﻥ ‪ Customers‬ﺗــﯜﺭﯨﻤﯩﺰ ﺋﯜﭼــﯜﻥ ﺗــﯜﺯﮔﻪﻥ ‪ CustomersEnumerable‬ﺗﯘﺭﺍﻗﻠﯩــﻖ‬


‫ﺗﯜﺭﯨــﺪﻩ ‪ Where‬ﻧــﺎﻣﻠﯩﻖ ﻛﯧﯖﻪﻳــﺘﻤﻪ ﻣﯧﺘﻮﺩﻧﯩــﯔ ﺋﯧﻨﯩﻘﻠﯩﻤﯩــﺴﻰ ﺑﯧﺮﻟﮕﻪﻧﻠﯩﻜــﻰ ﺋﯜﭼــﯜﻥ‪ ،‬ﻳــﯘﻗﯩﺮﯨﻘﻰ‬
‫‪Where(c‬ﺑﻮﻟـــﺴﺎ‬ ‫>=‬ ‫‪c.City‬‬ ‫==‬ ‫ﺋﺎﻟﻤﺎﺷـــﺘﯘﺭﯗﺵ ﺟﻪﺭﻳﺎﻧﯩـــﺪﺍ ﺋﯩـــﺸﻠﯩﺘﯩﻠﮕﻪﻥ )"‪"Brescia‬‬
‫‪ System.Linq.Enumerable‬ﺩﺍ ﺗﻪﻣﯩـــﻨﻠﻪﻧﮕﻪﻥ‪ ،‬ﺗﯩﺰﻣﯩﻼﺭﻏــــﺎ ﺋﻮﺭﺗــــﺎﻕ ﺋﯩــــﺸﻠﯩﺘﯩﻠﯩﺪﯨﻐﺎﻥ ‪Where‬‬
‫ﺑﻮﻟﻤﺎﺳﺘﯩﻦ ﺑﻪﻟﻜﻰ ‪ CustomersEnumerable‬ﺩﯨﻜﻰ ﻛـﯧﯖﻪﻳﻤﻪ ﻣﯧﺘﻮﺩﺗـﯘﺭ‪CustomersEnumerable).‬‬
‫ﺗﯜﺭﻯ ﭼﻮﻗـﯘﻡ ﻣﻪﺯﻛـﯘﺭ ﺗـﯜﺭ ﺋﯩﭽﯩـﺪﻩ ﺑﻮﻟﯘﺷـﻰ‪ ،‬ﻳـﺎﻛﻰ ﭼﺎﻗﯩﺮﯨﻠﻐـﺎﻥ ﺑﻮﻟﯘﺷـﻰ ﻛﯧـﺮﻩﻙ(‪ .‬ﺋﻪﻣـﺪﻯ ‪Linq‬‬
‫ﻛﯜﭼﯩﻨﯩﯔ ﮬﻪﻗﯩﻘﻰ ﻣﺎﮬﯩﻴﯩﺘﯩﻨﻰ ﭼﯜﺷﻪﻧﮕﻪﻧﺪﻩﻙ ﺑﻮﻟﯩﯟﺍﺗﻘﺎﻧﺴﯩﺰ؟‪...‬‬
‫ﻛﯧﯖﻪﻳــﺘﯩﻠﻤﻪ ﻣﯧﺘــﻮﺩ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﻧــﯚﯞﻩﺗﺘﻪ ﺑــﺎﺭ ﺑﻮﻟﻐــﺎﻥ ﺗــﯜﺭﻟﻪﺭﮔﻪ ﯞﺍﺭﯨــﺴﻠﯩﻖ ﻗﯩﻠﻤــﺎﻱ ﺗﯘﺭﯗﭘﻤــﯘ ﺋﯘﻧﯩــﯔ‬
‫ﺋﯩﻘﺘﯩﺪﺍﺭﯨﻨﻰ ﻳﯘﻗﯩﺮﻯ ﻛﯚﺗﯜﺭﻩﻟﻪﻳﻤﯩﺰ‪ .‬ﺋﻪﻣﻪﻟﯩﻴﻪﺗﺘﻪ‪ ،‬ﺑﯩﺰ ﻛﯧﻴﯩﻦ ﺳﯚﺯﻟﯩﻤﻪﻛﭽﻰ ﺑﻮﻟﻐﺎﻥ ‪Linq to Sql,‬‬
‫‪ Linq‬ﻟﻪﺭ ﺑﻮﻟـــﺴﺎ‪ ،‬ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﻣﻪﺷـــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻧﯩﯔ ﻗﺎﻳﺘـــﺎ ﺋﻪﻣﻪﻟـــﮕﻪ ﺋﺎﺷـــﯘﺭﯗﻟﯘﭖ‬ ‫‪to‬‬ ‫‪XML‬‬
‫ﺧﺎﺳﻼﺷﺘﯘﺭﯗﻟﻐﺎﻧﻠﯩﺮﯨﺪﯗﺭ‪ ،‬ﺧﺎﻻﺱ‪.‬‬

‫ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ‬

‫ﺋﺎﻟﻤﺎﺷــﺘﯘﺭﯗﺵ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻠﯩﺮﯨﻐﺎ ﺗﻪﯞﻩ ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻼﺭﺩﯨﻦ ‪،ToList ،ToArray ،AsEnumerable‬‬


‫‪ OfType ،ToLookup ،ToDictionary‬ﯞﻩ ‪ Cast‬ﻗﺎﺗﺎﺭﻟﯩﻘﻼﺭ‪ .‬ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷـﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺑﯩـﺰ‬
‫ﺋﺎﻟــــﺪﯨﻨﻘﻰ ﻣﻪﺯﻣــــﯘﻧﻼﺭﺩﺍ ﺋﯘﭼﺮﯨﻐــــﺎﻥ ﺑﯩــــﺮ ﻗﯩــــﺴﯩﻢ ﻣﻪﺳــــﯩﻠﯩﻠﻪﺭﻧﻰ ﮬﻪﻝ ﻗﯩﻠﯩــــﺶ ﻳﯜﺯﯨــــﺴﯩﺪﯨﻦ‬
‫ﺋﻮﺭﯗﻧﻼﺷﺘﯘﺭﯗﻟﻐﺎﻥ‪ .‬ﺑﻪﺯﯨﺪﻩ ﺑﯩﺰ ﻣﯘﻗﯩﻢ‪ ،‬ﺋﯩﻤﻤﻮﻧﯩﺘﭽﺎﻧﻠﯩﻘﻰ ﻛﯜﭼﻠﯜﻙ)ﺋﺎﺳﺎﻥ ﺋﯚﺯﮔﻪﺭﻣﻪﻳـﺪﯨﻐﺎﻥ( ﺑﻮﻟﻐـﺎﻥ‬
‫ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﻧﻪﺗﯩﺠﯩﻠﯩـــﺮﯨﮕﻪ ﺋﯧﮫﺘﯩﺠـــﺎﺝ ﺑﻮﻟـــﯘﭖ ﻗﺎﻟـــﺴﺎﻕ‪ ،‬ﻳﻪﻧﻪ ﺑﻪﺯﯨـــﺪﻩ ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﺧـــﺎﺱ‬
‫ﺳﯚﺯﻟﯩﺮﯨﻨﯩﯔ ﺋﻮﺭﻧﯩﻐﺎ ﻛﯚﭘﻤﺎﺱ ﻛﯧﯖﻪﻳﺘﻤﻪ ﻣﯧﺘﻮﺩﻻﺭﻧﻰ ﺋﺸﯩﻠﺘﯩﭗ ﻗﯧﻠﯩﺸﯩﻤﯩﺰ ﻣﯘﻣﻜﯩﻦ‪...‬‬

‫‪AsEnumerable‬‬
‫‪ AsEnumerable‬ﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫‪public static IEnumerable<T> AsEnumerable<T>( ‬‬
‫;)‪    this IEnumerable<T> source‬‬

‫‪ AsEnumerable‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﻣﻪﻧﺒﻪﻧﻰ ﺋﺎﺩﺩﻯ ﮬﺎﻟﺪﺍ >‪ IEnumerable<T‬ﻧﯩﯔ ﺋﻮﺑﯩﻜﺘﻰ ﮬﺎﻟﯩﺘﯩﺪﻩ‬


‫ﻗﺎﻳﺘﯘﺭﯗﭖ ﺑﯧﺮﯨﺪﯗ‪ .‬ﺑﯘﻧﯩﯖﻐﺎ ﺋﻮﺧﺸﺎﺵ ﭼﺎﻗﻤﺎﻕ ﺗﯧﺰﻟﯩﻜﯩﺪﯨﻜﻰ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﺑﯩﺰﻧﻰ ﻣﻪﻧﺒﻪ ﺋﯜﺳﺘﯩﺪﻩ‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪86‬‬

‫ﺋﺎﻟﺪﯨﻨﻘﻰ ﻣﻪﺯﻣﯘﻧﻼﺭﺩﺍ ﺳﯚﺯﻟﻪﭖ ﻛﯧﻠﯩﯟﺍﺗﻘﺎﻥ ﻛﯧﯖﻪﻳﺘﯩﻠﻤﻪ ﻣﯧﺘﻮﺩﻻﺭﻧﻰ ﻗﻮﻟﻠﯩﻨﯩﺶ ﺋﯩﻤﻜﺎﻧﯩﻴﯩﺘﯩﮕﻪ ﺋﯩﮕﻪ‬


‫ﻗﯩﻠﯩﺪﯗ‪ .‬ﻣﻪﺳﯩﻠﻪﻥ‪ :‬ﺗﯚﯞﻩﻧﺪﯨﻜﻰ ﻣﯩﺴﺎﻟﻐﺎ ﻗﺎﺭﺍﯓ‪:‬‬
‫ﻛﻮﺩ ‪4.57‬‬

‫‪Customers customersList = new Customers(customers); ‬‬
‫‪ ‬‬
‫‪var expr = ‬‬
‫‪    from   c in customersList.AsEnumerable() ‬‬
‫‪    where  c.City == "Brescia" ‬‬
‫‪    select c; ‬‬
‫‪ ‬‬
‫‪foreach (var item in expr) { ‬‬
‫‪    Console.WriteLine(item); ‬‬
‫‪} ‬‬

‫ﻛـــﻮﺩ ‪ 4.57‬ﺩﺍ ﺑﯩـــﺰ ‪ System.Linq.Enumerable‬ﺩﺍ >‪ IEnumerable<T‬ﺋﯜﭼـــﯜﻥ ﺋﯧﻨﯩﻘﯩﻼﻧﻐـــﺎﻥ‬


‫ﺋﯚﻟﭽﻪﻣﻠﯩﻚ ‪ Where‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﻰ ﺋﯩﺸﻠﻪﺗﺘﯘﻕ‪.‬‬

‫‪ ToArray‬ﺑﯩﻠﻪﻥ ‪ToList‬‬
‫‪ ToArray‬ﺑﯩﻠﻪﻥ ‪ ToList‬ﻻﺭ ﺑﻮﻟﺴﺎ ﻧﺎﮬﺎﻳﯩﺘﻰ ﻗﻮﻟﻠﯩﻨﯩﺸﭽﺎﻥ ﺋﺎﻟﻤﺎﺷـﺘﯘﺭﯗﺵ ﻣﻪﺷـﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺑﻮﻟـﯘﭖ‬
‫ﺋﺎﻳﺮﯨﻢ‪-‬ﺋﺎﻳﺮﯨﻢ ﮬﺎﻟﺪﺍ‪ IEnumerable<T> ،‬ﺗﯩﭙﻠﯩﻖ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﻨﻰ ‪ T‬ﻧﯩـﯔ ﺭﯦﺘـﻰ ][‪ T‬ﮔﻪ ﯞﻩ ‪ T‬ﻧﯩـﯔ‬
‫ﻛﯚﭘﻤﺎﺱ ﺗﯩﺰﻣﯩﺴﻰ >‪ List<T‬ﻏﺎ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯨﺪﯗ‪.‬‬
‫‪public static T[] ToArray<T>( ‬‬
‫‪    this IEnumerable<T> source); ‬‬
‫‪public static List<T> ToList<T>( ‬‬
‫;)‪    this IEnumerable<T> source‬‬

‫ﺑـﯘ ﻣﻪﺷـﻐﯘﻻﺗﭽﯩﻼﺭﻧﯩﯔ ﻧﻪﺗﯩﺠﯩـﺴﻰ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩﻨﯩـﯔ ﺋﺎﻟﻤﺎﺷـﺘﯘﺭﯗﻟﻐﺎﻥ ﺋﻪﻣﻪﻟـﻰ ﻛﯚﭘﻪﻳﻤﯩـﺴﻰ ﺑﻮﻟــﯘﭖ‪،‬‬


‫ﺋﻪﮔﻪﺭ ﺋـــﯘﻻﺭ ﺳﯜﺭﯛﺷـــﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨـــﺴﯩﻨﯩﯔ ﺋﯩﭽﯩـــﺪﻩ ﺋﯩـــﺸﻠﯩﺘﯩﻠﮕﻪﻧﺪﻩ ﻧﻪﺗﯩـــﺠﻪ ﻣﻪﻧـــﺒﻪ ﺗﯩﺰﻣﯩﻨﯩـــﯔ‬
‫ﺋﯚﺯﮔﯩﺮﯨﺸﯩﮕﻪ ﺋﻪﮔﯩﺸﯩﭗ ﺋﯚﺯﮔﻪﺭﻣﻪﻳﺪﯗ‪ .‬ﺗﯚﯞﻩﻧﺪﻩ ‪ ToList‬ﻧﯩﯔ ﺋﯩﺸﻠﯩﺘﯩﺸﺘﯩﻦ ﺑﯩﺮ ﻣﯩﺴﺎﻝ‪:‬‬
‫ﻛﻮﺩ ‪4.58‬‬

‫‪List<Customer> customersList = new List<Customer>(customers); ‬‬
‫‪ ‬‬
‫‪var expr = ‬‬
‫‪    from   c in customersList.ToList() ‬‬
‫‪    where  c.Country == Countries.Italy ‬‬
‫‪    select c; ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪87‬‬

‫‪ ‬‬
‫‪foreach (var item in expr) { ‬‬
‫‪    Console.WriteLine(item); ‬‬
‫‪} ‬‬

‫ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﯨﺴﯩﻨﯩﯔ ﻧﻪﺗﯩﺠﯩﺴﯩﻨﻰ ﻗﺎﻳﺘﺎ‪ -‬ﻗﺎﻳﺘﺎ ﭼﺎﺭﻻﺷﻘﺎ ﺗـﻮﻏﺮﺍ ﻛﻪﻟﮕﻪﻧـﺪﻩ ﺑـﯘ ﻣﻪﺷـﻐﯘﻻﺗﭽﯩﻼﺭ‬
‫ﻧﺎﮬﺎﻳﯩﺘﻰ ﺋﻪﺱ ﻗﺎﺗﯩﺪﯗ‪ .‬ﭼﯜﻧﻜﻰ ﻧﻮﺭﻣﺎﻝ ﮬﺎﻟﻪﺗﺘﻪ‪ ،‬ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙـﺎﺩﻩ ﻧﻪﺗﯩﺠﯩـﺴﯩﻨﻰ ﮬﻪﺭﺑﯩـﺮ ﻗﯧـﺘﯩﻢ‬
‫ﭼــﺎﺭﻻﺵ ﺋﯩﭙﺎﺩﯨﻨﯩــﯔ ﺑﯩــﺮ ﻗﯧــﺘﯩﻢ ﺋﯩﺠــﺮﺍ ﺑﻮﻟﯘﺷــﯩﻨﻰ ﻛﻪﻟﺘــﯜﺭﯛﭖ ﭼﯩﻘﯩﺮﯨــﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﺋﯩﭙــﺎﺩﻩ ﺳــﺎﻧﺪﺍﻧﻐﺎ‬
‫ﻣﻪﺷــﻐﯘﻻﺕ ﺋﯧﻠﯩــﭗ ﺑﯧﺮﯨﯟﺍﺗﻘــﺎﻥ ﺑﻮﻟــﺴﺎ‪ ،‬ﺋﯧﻨﯩﻘﻜــﻰ ﺋﯜﻧﯜﻣــﺪﯨﻦ ﺋﯘﺗﺘــﯘﺭﯗﭖ ﻗــﻮﻳﯩﻤﯩﺰ‪ .‬ﺷــﯘﯕﺎ ﺑﯘﻧــﺪﺍﻕ‬
‫ﺋﻪﮬﯟﺍﻟﻼﺭﺩﺍ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﭙﺎﺩﻩ ﻧﻪﺗﯩﺠﯩﺴﯩﻨﻰ ‪ ToList‬ﻳﺎﻛﻰ ‪ ToArray‬ﺋﺎﺭﻗﯩﻠﯩﻖ ﺋﻪﺯﺍﻻﺭﻧﯩﯔ ﺋﻪﻣﻪﻟﯩـﻲ‬
‫ﺗﻮﭘﻠﯩﺮﯨﻐﺎ ﺋﺎﻳﻼﻧﺪﯗﺭﯨﯟﯦﻠﯩﭗ ﺋﺎﻧﺪﯨﻦ ﻣﻪﺷﻐﯘﻻﺕ ﺋﯧﻠﯩﭗ ﺑﺎﺭﻏﺎﻥ ﺗﯜﺯﯛﻙ‪.‬‬
‫ﺗﯚﯞﻩﻧــﺪﯨﻜﻰ ﻣﯩــﺴﺎﻟﺪﺍ ‪ ToList‬ﺋــﺎﺭﻗﯩﻠﯩﻖ ﻣﻪﮬــﺴﯘﻻﺗﻼﺭﻏﺎ ﺋﯧﻠﯩــﭗ ﺑﯧﺮﯨﻠﻐــﺎﻥ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻙ ﻧﻪﺗﯩﺠﯩــﺴﻰ‬
‫ﻛﯚﭼﯩﺮﯨﯟﺍﻟﯩﺪﯗ‪:‬‬
‫ﻛﻮﺩ ‪4.59‬‬

‫‪var productsQuery = ‬‬
‫‪    (from p in products ‬‬
‫‪     where p.Price >= 30 ‬‬
‫‪     select p) ‬‬
‫‪    .ToList(); ‬‬
‫‪ ‬‬
‫‪var ordersWithProducts = ‬‬
‫‪    from c in customers ‬‬
‫‪        from   o in c.Orders ‬‬
‫‪        join   p in productsQuery ‬‬
‫‪               on o.IdProduct equals p.IdProduct ‬‬
‫‪        select new { p.IdProduct, o.Quantity, p.Price, ‬‬
‫‪                     TotalAmount = o.Quantity * p.Price}; ‬‬
‫‪ ‬‬
‫‪foreach (var order in ordersWithProducts) { ‬‬
‫‪    Console.WriteLine(order); ‬‬
‫‪} ‬‬

‫ﺋﻪﻣـــــﺪﻯ ‪ ordersWithProducts‬ﺋﯩﭙـــــﺎﺩﻩ ﻧﻪﺗﯩﺠﯩـــــﺴﯩﻨﻰ ﭼﺎﺭﻟﯩﻐﺎﻧـــــﺪﺍ‪ foreach ،‬ﺑﯚﻟﯩﻜﯩـــــﺪﯨﻜﻰ‬


‫‪ productsQuery‬ﻗﺎﻳﺘﺎ‪ -‬ﻗﺎﻳﺘﺎ ﺋﯩﺠﺮﺍ ﺑﻮﻟﻤﺎﻳﺪﯨﻐﺎﻥ ﺑﻮﻟﺪﻯ‪).‬ﺑﯘﻻﺭ ﺑﯘﺭﯗﻧﻘﻰ ﻣﻪﺯﻣﯘﻧﻼﺭﻧﯩﯔ ﻣﯩﺴﺎﻟﯩﺪﯨﻜﻰ‬
‫ﺋﯩﭙﺎﺩﯨﻠﻪﺭﻧﯩﯔ ﺋﯩﺴﯩﻤﻠﯩﺮﻯ(‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪88‬‬

‫‪ToDictionary‬‬
‫‪ ToDictionary‬ﺑﻮﻟــــﺴﺎ >‪ Dictionary<K,T‬ﻗﯘﺭﯨــــﺪﯨﻐﺎﻥ ﻣﻪﺷــــﻐﯘﻻﺗﭽﻰ ﺑﻮﻟــــﯘﭖ‪keySelector ،‬‬
‫ﻛﯚﺭﺳﻪﺗﻜﯜﭼﯩﺴﻰ ﮬﻪﺭﺑﯩﺮ ﺋﻪﺯﺍﻧﯩﯔ ﺋﺎﭼﻘﯘﭼﻠﯘﻕ ﺳﯚﺯﯨﻨﻰ ﺗﻪﻛﺸﯜﺭﯨﺪﯗ‪ elementSelector .‬ﺑﻮﻟـﺴﺎ)ﺋﻪﮔﻪﺭ‬
‫ﺗﻪﻣﯩﻨﻠﻪﻧﺴﻪ( ﮬﻪﺭﺑﯩﺮ ﺋﻪﺯﺍﻧﻰ ﺋﯧﻠﯩﺸﻘﺎ ﺋﯩﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪ .‬ﺑﯘ ﻛﯚﺭﺳﻪﺗﻜﯜﭼﻠﻪﺭ ﺗﯚﯞﻩﻧﺪﯨﻜﯩـﺪﻩﻙ ﺋﻪﻧـﺪﯨﺰﯨﻠﻪﺭﺩﻩ‬
‫ﺋﯩﭙﺎﺩﯨﻠﻪﻧﮕﻪﻥ‪:‬‬
‫‪public static Dictionary<K, T> ToDictionary<T, K>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector); ‬‬
‫‪public static Dictionary<K, T> ToDictionary<T, K>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector, ‬‬
‫‪    IEqualityComparer<K> comparer); ‬‬
‫‪public static Dictionary<K, E> ToDictionary<T, K, E>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector, ‬‬
‫‪    Func<T, E> elementSelector); ‬‬
‫‪public static Dictionary<K, E> ToDictionary<T, K, E>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector, ‬‬
‫‪    Func<T, E> elementSelector, ‬‬
‫‪    IEqualityComparer<K> comparer); ‬‬

‫ﮬﻪﻣﯩﻤﯩــﺰﮔﻪ ﺋﺎﻳــﺎﻥ‪ Dictionary<K,V> ،‬ﺗﯩﭙﯩــﺪﯨﻜﻰ ﮬﻪﺭ ﺑﯩــﺮ ﺋﯧﻠﯧﻤﯧﻨﺘﻨﯩــﯔ ﭼﻮﻗــﯘﻡ ﻗﯩﻤﻤﯩﺘــﻰ‬


‫ﺑﺎﺷــﻘﯩﻼﺭﻏﺎ ﺋﻮﺧــﺸﯩﻤﺎﻳﺪﯨﻐﺎﻥ ‪ K‬ﺗﯩﭙﻠﯩــﻖ ﺋــﺎﭼﻘﯘﭼﻠﯩﻖ ﺳــﯚﺯﻯ)ﻣﻪﻟــﯘﻡ ﺗﯩﭙﻠﯩــﻖ ﺋﻮﺑﻴﯧﻜﯩــﺖ ﺑﻮﻟــﺴﯩﻤﯘ‬
‫ﺑﻮﻟﯩﺪﯗ‪ (...‬ﺑﻮﻟﯘﺷﻰ ﻛﯧﺮﻩﻙ‪ .‬ﺷـﯘﯕﺎ ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩﻨـﻰ ‪ ToDictionary‬ﺋـﺎﺭﻗﯩﻠﯩﻖ >‪Dictionary<T,K‬‬
‫ﺗﯩﭙﻠﯩﻖ ﺗﻮﭘﻼﻣﻐﺎ ﺋﺎﻳﻼﻧﺪﯗﺭﻏﺎﻧﺪﺍ‪،‬ﮬﻪﺭ ﺑﯩﺮ ﺋﻪﺯﺍ ﺋﯜﭼﯜﻥ ‪ keySelector‬ﻛﯚﺭﺳﻪﺗﻤﯩﺴﻰ ﺋﺎﺭﻗﯩﻠﯩﻖ ﺑﯩﺮﯨﺪﯨﻦ‬
‫ﺑﯩﺮ ﺋـﺎﭼﻘﯘﭼﻠﯘﻕ ﺳـﯚﺯ ﺗـﺎﻟﻼﭖ ﺑﯧـﺮﯨﺶ ﻛﯧـﺮﻩﻙ‪ .‬ﺋﻪﮔﻪﺭ ﺗـﺎﻻﺵ ﺟﻪﺭﻳﺎﻧﯩـﺪﺍ ﺗﻪﻛـﺮﺍﺭ ﺋـﺎﭼﻘﯘﭼﻠﯘﻕ ﺳـﯚﺯ‬
‫ﺑﺎﻳﻘﺎﻟــــﺴﺎ ‪ ArgumentException‬ﺗﯩﭙﻠﯩــــﻖ ﺑﯩﻨﻮﺭﻣــــﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨــــﺪﯗ‪ .‬ﺋــــﺎﭼﻘﯘﭼﻠﯘﻕ ﺳــــﯚﺯﻟﻪﺭﻧﻰ‬
‫ﺳﯧﻠﯩــﺸﺘﯘﺭﯗﺷﺘﺎ ‪ comparer‬ﭘــﺎﺭﺍﻣﯧﺘﯩﺮﻯ ﺋــﺎﺭﻗﯩﻠﯩﻖ ﻳﻮﻟﻼﻧﻐــﺎﻥ ﺳﯧﻠﯩــﺸﺘﯘﺭﻏﯘﭺ ﺋﯩــﺸﻠﯩﺘﯩﻠﯩﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ‬
‫ﺗﻪﻣﯩﻨﻠﻪﻧﻤﯩـــﺴﻪ ﺳﯩـــﺴﺘﯧﻤﺎ ﻛﯚﯕﯜﻟـــﺪﯨﻜﻰ ﻗﯩﻤﻤﯩﺘﯩـــﺪﯨﻜﻰ ‪ EqualityComparer<K>.Default‬ﻧـــﻰ‬
‫ﺋﯩﺸﻠﯩﺘﯩﺪﯗ‪.‬‬
‫ﻛﻮﺩ ‪ 4.60‬ﺩﺍ ﺑﯩﺰ ‪ ToDictionary‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﻰ ﺋﯩﺸﻠﯩﺘﯩﭗ‪ ،‬ﺧﯧﺮﯨﺪﺍﺭﻻﺭﻧﯩﯔ ‪ dictionary‬ﺳـﯩﻨﻰ‬
‫ﻗﯘﺭﺩﯗﻕ‪) .‬ﺑﯘ ﻳﻪﺭﺩﯨﻜﻰ ‪ dictionary‬ﻟﯘﻏﻪﺕ ﺩﯦﮕﻪﻥ ﻣﻪﻧﯩﺴﻰ ﺑﺎﺭ‪ .‬ﺑﯘﻧـﺪﺍﻕ ﺋﺎﺗﺎﺷـﺘﯩﻜﻰ ﺳـﻪﯞﻩﺑﻤﯘ ﮬﻪﻡ‬
‫ﻟﯘﻏﻪﺗﺘﯩﻜﻰ ﮬﻪﺭﺑﯩﺮ ﺋﺎﭼﻘﯘﭼﻠﯘﻕ ﺳﯚﺯﻧﯩﯔ ﺑﯩﺮﺩﯨﻦ‪ -‬ﺑﯩﺮ ﺑﻮﻟﻐﺎﻧﻠﯩﻘﯩﺪﺍ(‬
‫ﻛﻮﺩ ‪4.60‬‬

‫‪var customersDictionary = ‬‬
‫‪    customers ‬‬
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪89‬‬

‫‪    .ToDictionary(c => c.Name, ‬‬
‫‪                  c => new {c.Name, c.City}); ‬‬

‫ﻳــﯘﻗﯩﺮﯨﻘﻰ ﻣﯩــﺴﺎﻟﺪﺍ‪ ،‬ﻣﻪﺷــﻐﯘﻻﺗﭽﯩﻨﯩﯔ ﺑﯩﺮﯨﻨﭽــﻰ ﭘــﺎﺭﺍﻣﯧﺘﯩﺮﻯ )‪ (c=?c.Name‬ﺑﻮﻟــﺴﺎ ‪keySelector‬‬


‫ﻛﯚﺭﺳﻪﺗﻤﯩــﺴﻰ ﺑﻮﻟــﯘﭖ‪ ،‬ﺋــﯘ »ﻧﻪﺗﯩــﺠﻪ ﻟﯘﻏﯩﺘﯩــﺪﯨﻜﻰ ﮬﻪﺭ ﺑﯩــﺮ ﺋﯧﻠﯧﻤﯧﻨــﺖ ﺋﯜﭼــﯜﻥ ﺧﯧﺮﯨــﺪﺍﺭﻧﯩﯔ ﻧــﺎﻡ‬
‫ﺧﺎﺳﻠﯩﻘﯩﻨﻰ ﺋـﺎﭼﻘﯘﭺ ﺳـﯚﺯ ﻗﯩﻠﯩـﭗ ﺑﯧﻜﯩـﺖ« ﺩﯦﮕﻪﻧﻨـﻰ ﻛﯚﺭﺳـﯩﺘﯩﭗ ﺑﯧﺮﯨـﺪﯗ‪ .‬ﺋﯩﻜﻜﯩﻨﭽـﻰ ﭘـﺎﺭﺍﻣﯧﺘﯩﺮﻯ‬
‫‪ elementSelector‬ﺑﻮﻟﯘﭖ‪ ،‬ﺋﯘ ﺧﯧﺮﯨﺪﺍﺭﻧﯩﯔ ﻧﺎﻣﻰ ﺑﯩـﻠﻪﻥ ﺷـﻪﮬﻪﺭ ﺧﺎﺳـﻠﯩﻘﯩﻨﯩﻼ ﺋـﯚﺯ ﺋﯩﭽﯩـﮕﻪ ﺋﺎﻟﻐـﺎﻥ‬
‫ﻧﺎﻣــﺴﯩﺰ ﺗﯩﭙﻠﯩــﻖ ﺋــﻮﺑﻴﯧﻜﯩﺘﻨﻰ ﻟــﯘﻏﻪﺗﺘﯩﻜﻰ ﮬﻪﺭ ﺑﯩــﺮ ﺋﯧﻠﯧﻤﯧﻨﺘﻨﯩــﯔ ﻗﯩﻤــﻤﻪﺕ ﺑــﯚﻟﯩﻜﻰ )‪ (K‬ﻗﯩﻠﯩــﭗ‬
‫ﺑﻪﻟﮕﯩﻠﻪﺷــﻨﻰ ﻛﯚﺭﺳــﯩﺘﯩﺪﯗ‪ .‬ﺗﯚﯞﻩﻧﺪﯨﻜﯩــﺴﻰ ﻛــﻮﺩ ‪ 4.60‬ﺩﯨﻜــﻰ ﺳﯜﺭﯛﺷــﺘﯜﺭﯛﻛﻨﯩﯔ ﻧﻪﺗﯩﺠﯩــﺴﯩﻨﯩﯔ‬
‫ﻣﻪﺯﻣﯘﻧﻰ‪:‬‬
‫‪K‬‬ ‫‪E‬‬
‫]}‪[Paolo, {Name=Paolo, City=Brescia‬‬
‫]}‪[Marco, {Name=Marco, City=Torino‬‬
‫]}‪[James, {Name=James, City=Dallas‬‬
‫]}‪[Frank, {Name=Frank, City=Seattle‬‬

‫ﺋﻪﺳــﻜﻪﺭﺗﯩﺶ‪ :‬ﺧــﯘﺩﺩﻯ ‪ ToList,ToArray‬ﻻﺭﻏــﺎ ﺋﻮﺧــﺸﺎ‪ ToDictionary ،‬ﺋــﺎﺭﻗﯩﻠﯩﻖ ﺋﯧﺮﯨــﺸﻜﻪﻥ‬


‫ﻧﻪﺗﯩﺠﯩﻤﯘ ﺳﯜﺭﯛﺷﺘﯜﺭﯛﻙ ﺋﯩﺠﺮﺍ ﻧﻪﺗﯩﺠﯩﺴﯩﻨﯩﯔ ﺋﻪﻣﻪﻟﯩﻲ ﻛﯚﭘﻪﻳﺘﯩﻠﻤﯩﺴﺴﯩﺪﯨﻦ ﺋﯩﺒﺎﺭﻩﺕ‪.‬‬

‫‪ToLookup‬‬
‫‪ ToLookup‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩــﺴﻰ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣﯩــﺪﯨﻦ >‪ Lookup<T,K‬ﺗﯩﭙﻠﯩــﻖ ﺗــﻮﭘﻼﻡ ﮬﺎﺳــﯩﻞ ﻗﯩﻠﯩــﺶ‬
‫ﯞﻩﺯﯨﭙﯩﺴﯩﻨﻰ ﺋﯚﺗﻪﻳﺪﯗ‪ Lookup<T,K> .‬ﻧﯩﯔ ﺋﯧﻨﯩﻘﻠﯩﻤﯩﺮﻯ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫‪public class Lookup<K, T> : IEnumerable<IGrouping<K, T>> { ‬‬
‫‪    public int Count { get; } ‬‬
‫‪    public IEnumerable<T> this[K key] { get; } ‬‬
‫‪    public bool Contains(K key); ‬‬
‫‪    public IEnumerator<IGrouping<K, T>> GetEnumerator(); ‬‬
‫}‬

‫>‪ Lookup<T,K‬ﺗﯩﭙﯩﻨﯩﯔ ﮬﻪﺭ ﺑﯩﺮ ﺋﻮﺑﯩﻴﯩﻜﺘﻰ ﺑﯩﺮﺩﺍﻧﻪ »ﺑﯩﺮﺩﯨﻦ ﻛﯚﭘﻜﻪ« ﻟﯘﻏﯩﺘﯩﮕﻪ ﻣـﺎﺱ ﻛﯧﻠﯩـﺪﯗ‪.‬‬
‫ﻳﻪﻧﻰ ‪ Linq‬ﺩﯨﻜﻰ ‪ GroupJoin‬ﺧﺎﺱ ﺳﯚﺯﯨﻨﯩﯔ ﻧﻪﺗﯩﺠﯩﺴﯩﮕﻪ ﺋﻮﺧﺸﯩـﺸﯩﭗ ﻛﯧﺘﯩـﺪﯗ‪ .‬ﺗﯚﯞﻩﻧﺪﯨﻜﯩـﺴﻰ‬
‫‪ ToLookup‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﯩﻨﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﻠﯩﺮﻯ‪:‬‬
‫‪public static Lookup<K, T> ToLookup<T, K>( ‬‬
‫‪    this IEnumerable<T> source, ‬‬
‫‪    Func<T, K> keySelector); ‬‬
‫‪public static Lookup<K, T> ToLookup<T, K>( ‬‬
www.udmish.cn ‫ ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬LINQ 90

    this IEnumerable<T> source, 
    Func<T, K> keySelector, 
    IEqualityComparer<K> comparer); 
public static Lookup<K, E> ToLookup<T, K, E>( 
    this IEnumerable<T> source, 
    Func<T, K> keySelector, 
    Func<T, E> elementSelector); 
public static Lookup<K, E> ToLookup<T, K, E>( 
    this IEnumerable<T> source, 
    Func<T, K> keySelector, 
    Func<T, E> elementSelector, 
    IEqualityComparer<K> comparer);

elementSelector ،‫ ﻛﯚﺭﺳﻪﺗﻜﯜﭼﯩـﺴﻰ‬keySelector ‫ ﺑﯘﻧﯩﯖـﺪﯨﻤﯘ‬،‫ ﺩﯨﻜﯩﮕﻪ ﺋﻮﺧﺸﺎﺵ‬ToDictionary


.‫ ﺳﯧﻠﯩﺸﺘﯘﺭﻏﯘﭼﯩﻠﯩﺮﻯ ﺑﺎﺭ‬comparer ‫ﻛﯚﺭﺳﻪﺗﻜﯜﭼﯩﺴﻰ ﯞﻩ‬
‫ ﺩﯨﻜــﻰ ﻣﯩــﺴﺎﻟﺪﺍ ﻣﻪﺯﻛــﯘﺭ ﻣﻪﺷ ـﻐﯘﻻﺗﭽﯩﻨﻰ ﺋﯩــﺸﻠﯩﺘﯩﭗ ﺗــﯘﺭﯗﭖ ﮬﻪﺭﺑﯩــﺮ ﻣﻪﮬــﺴﯘﻻﺗﻘﺎ ﻗﺎﺭﺗــﺎ‬4.61 ‫ﻛــﻮﺩ‬
:‫ﺯﺍﻛﺎﺯﻻﺭﻏﺎ ﻗﺎﻧﺪﺍﻕ ﺋﯧﺮﯨﺸﯩﺶ ﺋﯘﺳﯘﻟﻰ ﻛﯚﺭﺳﯩﺘﯩﻠﯩﺪﯗ‬
4.61 ‫ﻛﻮﺩ‬

var ordersByProduct = 
    (from c in customers 
         from   o in c.Orders 
         select o) 
    .ToLookup(o => o.IdProduct); 
 
Console.WriteLine( "\n\nNumber of orders for Product 1: {0}\n", 
                   ordersByProduct[1].Count()); 
 
foreach (var product in ordersByProduct) { 
    Console.WriteLine("Product: {0}", product.Key); 
    foreach(var order in product) { 
        Console.WriteLine("  {0}", order); 

:‫ﺗﯚﯞﻩﻧﺪﯨﻜﯩﺴﻰ ﻳﯘﻗﯩﺮﯨﻘﻰ ﻛﻮﺩﻧﯩﯔ ﺋﯩﺠﺮﺍ ﻧﻪﺗﯩﺠﯩﺴﻰ‬


Product: 1
3 - False - January – 1
10 - False - July – 1
Product: 2
5 - True - May – 2
‫‪www.udmish.cn‬‬ ‫‪ LINQ‬ﮬﻪﻗﻘﯩﺪﻩ ﺳﺎﯞﺍﺕ‬ ‫‪91‬‬

‫‪Product: 3‬‬
‫‪20 - True - December – 3‬‬
‫‪20 - True - December – 3‬‬
‫‪Product: 5‬‬
‫‪20 - False - July - 5‬‬

‫‪ OfType‬ﺑﯩﻠﻪﻥ ‪Cast‬‬
‫‪ OfType‬ﺑﯩـــﻠﻪﻥ ‪ Cast‬ﺋﺎﻟﻤﺎﺷـــﺘﯘﺭﯗﺵ ﻣﻪﺷـــﻐﯘﻻﺗﭽﯩﻠﯩﺮﻯ ﺋﯩﭽﯩـــﺪﯨﻜﻰ ﺋﻪﯓ ﺋـــﺎﺧﯩﺮﯨﻘﻰ ﺋﯩﻜﻜﯩـــﺴﻰ‪.‬‬
‫‪ OfType‬ﻣﻪﻧﺒﻪﺩﯨﻜﻰ ﺋﻪﺯﺍﻻﺭﻧﻰ ﭼﺎﺭﻻﭖ ﭘﻪﻗﻪﺕ ﺗﯩﭙﻰ ‪ T‬ﺑﻮﻟﻐﺎﻧﻨﯩﻼ ﻳﯩﻐﯩﯟﺍﻟﯩﺪﯗ)ﺷﯘﻧﯩﯖﺪﯨﻦ ﻛﯚﺭﯨﯟﯦﻠﺸﻘﺎ‬
‫ﺑﻮﻟﯩﺪﯗ‪ ،‬ﺑﯩﺮ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﺋﻪﺯﺍﻻﺭ ﺋﻮﺧﺸﯩﻤﯩﻐﺎﻥ ﺗﯩﭙﻠﯩـﻖ ﺑﻮﻟﯘﺷـﯩﻤﯘ ﻣـﯘﻣﻜﯩﻦ(‪ .‬ﻣﻪﺳـﯩﻠﻪﻥ‪ :‬ﺋﻮﺑﯩﻜﯩﺒﯩﺘﻘـﺎ‬
‫ﻳﯜﺯﻟﻪﻧﮕﻪﻥ ﭘﺮﻭﮔﺮﺍﻣﻤﺎ ﻻﻳﮫﯩﻴﯩﻠﻪﺵ ﭘﯩﺮﯨﻨﺴﯩﭙﻰ ﺑـﻮﻳﯩﭽﻪ‪ ،‬ﻣﻪﻧـﺒﻪ ﺗﯩﺰﻣﯩـﺪﺍ ﺑﻪﻟﻜﯩـﻢ ﺋﻮﺧـﺸﺎﺵ ﺋﺎﺗﯩـﺪﯨﻦ‬
‫ﺑﻮﻟﻐــﺎﻥ ﺋﻮﺧــﺸﯩﻤﯩﻐﺎﻥ ﺗﯩﭙﻠﯩــﻖ ﺋﻪﺯﺍﻻﺭ ﺑﻮﻟﯘﺷــﻰ ﻣــﯘﻣﻜﯩﻦ)ﺋﻮﺧــﺸﺎﺵ ﺑﯩــﺮ ﺗﯩﭙﻘــﺎ ﯞﺍﺭﯨــﺴﻠﯩﻖ ﻗﯩﻠﻐــﺎﻥ(‪.‬‬
‫ﮔﻪﺭﭼﻪ ﺋﯘﻻﺭﻧﯩﯔ ﮬﻪﻣﻤﯩﺴﻰ ﺋﺎﺗﯩﺴﯩﻨﯩﯔ ﺋﯩﻘﺘﯩﺪﺍﺭﻯ ﺑﻮﻟﺴﯩﻤﯘ ﻟﯧﻜﯩﻦ ﻳﻪﻧﯩﻼ ﺑﺎﺷﻘﺎ‪ -‬ﺑﺎﺷﻘﺎ ﺗﯩﭗ‪.‬‬
‫‪public static IEnumerable<T> OfType<T>( ‬‬
‫;)‪    this IEnumerable source‬‬

‫ﺋﻪﮔﻪﺭ ﺗﻪﻣﯩﻨﻠﯩﮕﻪﻥ ﺗﯩﭗ ‪ T‬ﻧﯩﯔ ﺋﻮﺑﯩﻴﯩﻜﺘﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﺍ ﺑﺎﻳﻘﺎﻟﻤﯩﺴﺎ‪ ،‬ﻗﯘﺭﯗﻕ ﺗﯩﺰﻣﺎ ﻗﺎﻳﺘﯘﺭﯨﺪﯗ‪.‬‬
‫‪ Cast‬ﻣﻪﺷﻐﯘﻻﺗﭽﯩﺴﻰ ﻣﻪﻧﺒﻪ ﺗﯩﺰﻣﯩﺪﯨﻜﻰ ﮬﻪﺭﺑﯩﺮ ﺋﻪﺯﺍﻧﻰ ﭼﺎﺭﻻﺵ ﺟﻪﺭﻳﺎﻧﯩﺪﺍ ﺋﯘﻧﯩﯔ ﺗﯩﭙﯩﻨﻰ ﺑﯧـﺮﯨﻠﮕﻪﻥ‬
‫‪ T‬ﻏــــــﺎ ﺋﺎﻳﻼﻧــــــﺪﯗﺭﯗﭖ ﻳﯩﻐﯩﯟﺍﻟﯩــــــﺪﯗ‪ .‬ﺋﻪﮔﻪﺭ ﺋﺎﻟﻤﺎﺷــــــﺘﯘﺭﯗﺵ ﻣﯘﯞﺍﭘﯩﻘﯩﻴﻪﺗﻠﯩــــــﻚ ﺑﻮﻟﻤﯩــــــﺴﺎ‬
‫‪ InvalidCastException‬ﺗﯩﭙﻠﯩﻖ ﺑﯩﻨﻮﺭﻣﺎﻟﻠﯩﻖ ﭼﯩﻘﯩﺮﯨﺪﯗ‪ .‬ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﺴﻰ ﺗﯚﯞﻩﻧﺪﯨﻜﯩﭽﻪ‪:‬‬
‫‪public static IEnumerable<T> Cast<T>( ‬‬
‫;)‪    this IEnumerable source‬‬

‫ﺋﯘﻧﯩﯔ ﺋﻪﻧﺪﯨﺰﯨﺴﯩﺪﯨﻦ ﺷﯘﻧﻰ ﻛﯚﺭﯨﯟﺍﻻﻻﻳﻤﯩﺰﻛﻰ‪ ،‬ﻣﻪﻧـﺒﻪﮔﻪ ‪ IEnumerbale‬ﺗﯩﭙﻠﯩـﻖ ﮬﻪﺭﻗﺎﻧـﺪﺍﻕ ﺗﯩﺰﻣـﺎ‬


‫ﻗﻮﺑــﯘﻝ ﻗﯩﻠﯩﻨﯩــﺪﯨﻐﺎﻥ ﺑﻮﻟــﯘﭖ‪ ،‬ﺋﻪﮔﻪﺭ ﺋــﯘﻧﻰ >‪ IEnumerrable<T‬ﻏــﺎ ﺋﺎﻳﻼﻧﺪﯗﺭﺍﻟﯩــﺴﺎ ‪ ،‬ﺋــﯘ ﭼﺎﻏــﺪﺍ‬
‫ﺋﻪﺳﻠﯩﺪﯨﻜﻰ ﺋﯧﻨﻘﺴﯩﺰ ﺗﯩﭙﻠﯩﻖ ﺗﯩﺰﻣﯩﻐﯩﻤﯘ ‪ Linq‬ﻧﻰ ﻗﻮﻟﻠﯩﻨﺎﻻﻳﻤﯩﺰ ﺩﯦﮕﻪﻥ ﮔﻪﭖ‪.‬‬
‫ﺋﻪﺳﻜﻪﺭﺗﯩﺶ‪ OfType :‬ﺑﯩﻠﻪﻥ ‪ Cast‬ﺩﯨـﻦ ﻗﺎﻳﺘﻘـﺎﻥ ﮬﻪﺭﺑﯩـﺮ ﺋﻪﺯﺍ ﻣﻪﻧﺒﻪﺩﯨﻜـﻰ ﺋﻪﺳـﻠﻰ ﺋﻮﺑﻴﯧﻜﯩﺘﻨﯩـﯔ‬
‫ﭼﺎﻗﯩﺮﯨﻠﻤﯩــﺴﻰ ﺑﻮﻟــﯘﭖ‪ ،‬ﺋــﯘﻻﺭ ﻳﯧﯖﯩــﺪﯨﻦ ﻛﯚﭼﯜﺭﯛﻟﻤﻪﻳــﺪﯗ‪ OfType .‬ﻧﻪﺗﯩﺠﯩــﺴﻰ ﻣﻪﻧــﺒﻪ ﺗﯩﺰﻣﯩﻨﯩــﯔ‬
‫ﻛﯚﭼﯜﺭﯛﻟﻤﯩﺴﻰ ﺋﻪﻣﻪﺱ‪ .‬ﺋﯘ ﻧﻪﺗﯩﺠﯩﮕﻪ ﻧﯩﺴﺒﻪﺗﻪﻥ ﺋﯩﺸﻠﯩﺘﯩﺶ ﺋﯧﻠﯩﭗ ﺑﯧﺮﯨﻠﮕﻪﻧﺪﯨﻼ ﺋﺎﻧـﺪﯨﻦ ﻗﯘﺭﯗﻟﯩـﺪﯗ‪.‬‬
‫ﺑﯘ ﻳﯧﺮﻯ ﺑﺎﺷﻘﺎ ﺋﺎﻟﻤﺎﺷﺘﯘﺭﯗﺵ ﻣﻪﺷﻐﯘﻻﺗﭽﯩﻠﯩﺮﯨﺪﯨﻦ ﭘﻪﺭﻗﻠﯩﻨﯩﺪﯗ‪.‬‬

You might also like