рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ foreach рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред рдЖрдк рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рдкрд╣рд▓реЗ рдХреНрд╖рдг рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЖрдк рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рджреВрд╕рд░реЗ рдХреНрд╖рдг рдХреЛ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВред
рдРрд░реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд┐рдЫрд▓рд╛ рд▓реЗрдЦрдкрд╣рд▓рд╛ рдХреНрд╖рдг
рдЗрдВрдЯрд░рд╡реНрдпреВ рдореЗрдВ рд╡реЗ рдЕрдХреНрд╕рд░ рдкреВрдЫрддреЗ рд╣реИрдВ - "
foreach
рд╕рд╛рде рдЖрдкрдХреА рдХрдХреНрд╖рд╛ рдХреЛ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ?" рдЗрд╕ рд╕рд╡рд╛рд▓ рдХрд╛ рдЬрд╡рд╛рдм рдЖрдорддреМрд░ рдкрд░ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рдЧрддрд╛ рд╣реИ - "рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВред" рдпрд╣ рдЙрддреНрддрд░ рд╕рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдореЗрдВ рдпрд╣ рдЬрд╡рд╛рдм рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдФрд░ рдореИрдВ рдЗрд╕реЗ рдЧрд▓рдд рдорд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рд╕реЗ рдХрднреА рдирд╣реАрдВ рдорд┐рд▓рд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ,
foreach
рдмрддрдЦ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ рдХреЛ
foreach
рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
foreach
GetEnumerator
рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдЬреЛ рдХрд┐ рдХреБрдЫ рд▓реЗ рдЬрд╛рдП рдЬреЛ рдПрдХ
MoveNext
рд╡рд┐рдзрд┐ рдФрд░ рдПрдХ
Current
рдЧреБрдг рд╣реИред
рдЗрди рддрд░реАрдХреЛрдВ рдХреЛ рдпрд╛рдж рд░рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рдЧрд▓рдд рд╡рд░реНрдЧ рдХреЛ
foreach
рдореЗрдВ
foreach
рд╕рдВрдХрд▓рдХ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдЖрдкрдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдХрдХреНрд╖рд╛ рдореЗрдВ рдХреНрдпрд╛ рдЧрд╛рдпрдм рд╣реИред
рдЙрджрд╛рд╣рд░рдг
рдЯреЗрд╕реНрдЯ
foreach
:
class Program { static void Main(string[] args) { var container = new Container(); foreach (var item in container) { } } }
рдЧрд▓рдд рдХрдВрдЯреЗрдирд░:
public class Container { }
рд╕рдВрдХрд▓рдХ рддреНрд░реБрдЯрд┐:
foreach statement cannot operate on variables of type 'Container' because 'Container' does not contain a public definition for 'GetEnumerator'
рдХрдВрдЯреЗрдирд░ рдФрд░ рдкреНрд░рдЧрдгрдХ рд╡рд░реНрдЧ рдореЗрдВ
GetEnumerator
рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВред
рд╕рд╣реА рдХрдВрдЯреЗрдирд░:
public class Container { public Enumerator GetEnumerator() { return new Enumerator(); } }
рдЧрд▓рдд рдЧрдгрдирд╛рдХрд░реНрддрд╛:
public class Enumerator { }
рд╕рдВрдХрд▓рдХ рддреНрд░реБрдЯрд┐:
foreach requires that the return type 'Enumerator' of 'Container.GetEnumerator()' must have a suitable public MoveNext method and public Current property
рдПрдиреНрдпреВрдорд░реЗрдЯрд░ рдореЗрдВ
MoveNext
рд╡рд┐рдзрд┐ рдФрд░
Current
рдЧреБрдг рдЬреЛрдбрд╝реЗрдВред
рд╕рд╣реА рдЧрдгрдирд╛рдХрд░реНрддрд╛:
public class Enumerator { public bool MoveNext() { return false; } public object Current { get { return null; } } }
рдЕрдм рдХрдВрдкрд╛рдЗрд▓рд░ рдареАрдХ рд╣реИред
рдиреЛрдЯ:
Current
рд╕рдВрдкрддреНрддрд┐ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреА рд╣реИ, рджреЛрдиреЛрдВ ref type
рдФрд░ value type
ref type
ред рджрд░рдЕрд╕рд▓, рдпрд╣ рдЙрд╕ рд╕рдордп рдбрдХрд╛рд░ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд╛ рдХрд╛рд░рдг рдерд╛, рдЬрдм рдХреЛрдИ рдРрд╕реА generics
рдирд╣реАрдВ рдереА, рдЬрд┐рд╕рд╕реЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ boxing
рдФрд░ unboxing
рд╕реЗ рдмрдЪрд╛ рдЬрд╛ рд╕рдХреЗредрджреВрд╕рд░рд╛ рдХреНрд╖рдг
рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдореЗрдВ,
IDisposable
рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреНрд░рд╢реНрди рд╣реИрдВ рдФрд░ рдореИрдиреБрдЕрд▓ рд╕рдВрд╕рд╛рдзрди рдкреНрд░рдмрдВрдзрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдкреНрд░рд╢реНрди рд╣реИ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ
Dispose
рд╡рд┐рдзрд┐ рдХреЛ рдХреИрд╕реЗ рдХреЙрд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрддреНрддрд░ рд╣рдо рд╕рднреА рдЬрд╛рдирддреЗ рд╣реИрдВ -
using()
рдХрдерди
using()
рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп
Dispose
рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЙрддреНрддрд░ рд╕рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдзреВрд░рд╛ рд╣реИ!
Dispose
рд╡рд┐рдзрд┐ рдХрд╛
using()
рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рджреЛ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
using()
, рдпрд╣ рдПрдиреНрдпреВрдорд░реЗрдЯрд░ рдХреЗ рд▓рд┐рдП
foreach
рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдПрдиреНрдпреВрдорд░реЗрдЯрд░
IDisposable
рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг
Dispose
рд╕рд╛рде
Dispose
:
using System; public class Enumerator : IDisposable { public bool MoveNext() { return false; } public object Current { get { return null; } } public void Dispose() { Console.WriteLine("Dispose"); } }
рдЕрдм рдЬрдм рд╣рдо рдЙрджрд╛рд╣рд░рдг рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХрдВрд╕реЛрд▓ рдореЗрдВ "рдбрд┐рд╕реНрдкреЛрдЬрд╝" рд▓рд╛рдЗрди рджреЗрдЦреЗрдВрдЧреЗред
рдЬреЛ рд▓реЛрдЧ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рдЙрдирдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдБ рдХреЛрдб рд╣реИ рдЬреЛ рд╕рдВрдХрд▓рдХ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ:
Container container = new Container(); Enumerator enumerator = container.GetEnumerator(); try { while (enumerator.MoveNext()) { var element = enumerator.Current;
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рд╕рднреА рдХрд╛ рдзрдиреНрдпрд╡рд╛рдж!