Enumerator(Iterator)
: ์งํฉ์ ์ธ ๋ฐ์ดํฐ์ ์ผ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ํ๋์ฉ ํธ์ถ์์๊ฒ ๋ณด๋ด์ฃผ๊ฒ ํ๋ ๊ธฐ๋ฅ => ๋ฐ๋ณต์yield
ํค์๋๋ ํธ์ถ์์๊ฒ ์ปฌ๋ ์ ๋ฐ์ดํฐ๋ฅผ ํ๋์ฉ ๋ฆฌํดํ ๋ ์ฌ์ฉํ๋ ํค์๋yield
์ฌ์ฉ๋ฐฉ์yield return
: ์ปฌ๋ ์ ๋ฐ์ดํฐ๋ฅผ ํ๋์ฉ ๋ฆฌํดํ๋๋ฐ ์ฌ์ฉyield break
: ๋ฆฌํด์ ์ค์งํ๊ณIteration
๋ฃจํ๋ฅผ ๋น ์ ธ๋์ฌ๋ ์ฌ์ฉ
IEnumerator == ๋ฐ์ดํฐ๋ฅผ ๋ฆฌํด(Getter)ํ๋ ์ด๊ฑฐ์
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
Current
- ์ฝ๊ธฐ ์ ์ฉ ํ๋กํผํฐ๋ก ํ์ฌ ์์น์ ๋ฐ์ดํฐ๋ฅผ object ํ์ ์ผ๋ก ๋ฆฌํดํ๋ค.
- object๋ System.Object์ ๊ฐ๋ค.
MoveNext
(=> Java์ hasNext()์ ์ ์ฌ)- ๋ค์ ์์น๋ก ์ด๋ํ๋๋ฐ ๋ค์ ์์น์ ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฉด true, ์์ผ๋ฉด false.
- ๊ทธ๋์ ๋ณดํต ์ปฌ๋ ์ ์ธ๋ฑ์ค๋ฅผ 1์ฉ ์ฆ๊ฐ ์์ผ ์ปฌ๋ ์ ์ ๋์ ๋๋ฌ ํ๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ bool์ ๋ฐํํ๋ ์์ผ๋ก ๊ตฌํํจ.
Reset
- ์ธ๋ฑ์ค๋ฅผ ์ด๊ธฐ ์์น๋ก ์ด๊ธฐํ
- ๋ณดํต ์ปฌ๋ ์ ์ ์ธ๋ฑ์ค๋ฅผ -1๋ก ์ค์ ํ๋์์ผ๋ก ๊ตฌํ
IEnumerator
๋ฅผ ๋ฆฌํดํ๋ ๋ชจ๋ ํจ์๋ref
,out
๋งค๊ฐ๋ณ์๊ฐ ํ์ฉ๋์ง ์๋๋ค. ๋ํ ๋๋ค ํจ์์ ์ฌ์ฉํ ์๋ ์๋ค.
IEnumerable == IEnumerator(์ด๊ฑฐ์)๋ฅผ Getํ๋๋ฐ ํ์ํ ์ธํฐํ์ด์ค
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
๊ฐ์ฒด๋ก
foreach
๋ฌธ์ ๋๋ฆฌ๊ธฐ ์ํด์๋ ๊ทธ ๊ฐ์ฒด ํ์ ์ดIEnumerable
์ ์์๋ฐ์ ํด๋์ค์ฌ์ผ ํ๋ค.IEnumerable์ ์์๋ฐ์ GetEnumerator()์ ๊ตฌํํ ํด๋์ค์ด์ด์ผ
foreach
๋ก ๋ด๋ถ ๋ฐ์ดํฐ๋ฅผ ์ด๊ฑฐํ ์ ์๋ค.๋ง์ฐฌ๊ฐ์ง๋ก IEnumerable ๋ฅผ ๋ฆฌํดํ๋ ๋ชจ๋ ํจ์๋
ref
,out
๋งค๊ฐ๋ณ์๊ฐ ํ์ฉ๋์ง ์๋๋ค. ๋ํ๋๋ค
ํจ์์ ์ฌ์ฉํ ์ ๋ ์๋ค.
namespace yieldEx
{
class Program
{
static IEnumerable<int> GetNumber()
{
yield return 1;
yield return 2;
yield return 3;
}
static void Main(string[] args)
{
foreach (int i in GetNumber())
{
Console.WriteLine(i);
}
}
}
}
Output
1
2
3
IEnumerator ์ค์ต
using System.Collections;
namespace yieldEx2
{
class MyList
{
private int[] data = { 1, 2, 3, 4, 5 };
//๋ฐฐ์ด์ ์ด๋ฏธ IEnumerator์ IEnumerable์ ๊ตฌํํ๊ณ ์๋ค.
public IEnumerator GetEnumerator()
{
int i = 0;
while (i < data.Length)
{
yield return data[i]; // 2. yield๋ฅผ ๋ง๋๋ฉด ํธ์ถ๋ ๊ณณ์ ๋จผ์ return์ ํด์ฃผ๊ณ ๋ค์ ํธ์ถ๋ ๋๊น์ง ๋๊ธฐ.
//IEnumator๋ฅผ ๋ฆฌํด๊ฐ์ผ๋ก ๋์๋์๋ yield ๋ฌธ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ฆฌํด์ ํด์ผํ๋ค.
// yield๋ฅผ ๋ง๋๋ฉด ํธ์ถ๋ ๊ณณ์ผ๋ก ๋ค์ ๋์๊ฐ ๊ฐ์ return ํ ๋ค ๋ค์ ๋์์ ๋น๋๊ธฐ์ ์ผ๋ก ๋์์ ํ๋ค.
i++;// 4. ๋ณต๊ทํ ํด๋น์ฝ๋ ์คํํ๊ณ while๋ฌธ ๋์ ์คํํ๋ฉฐ ์ผ๋ จ์ ๋ฐ๋ณต๊ณผ์ ์ ์งํ.
}
}
// IEnumerable ์ธํฐํ์ด์ค๋ GetEnumerator()๋ฉ์๋ ํ๋๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
// ์ด๋ GetEnumerator()๋ฉ์๋๋ IEnumerator๋ฅผ ๊ตฌํํ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํด์ค๋ค.
}
class Program
{
static void Main(string[] args)
{
var list = new MyList();
foreach(var item in list)
// 1. var item in list์ in์์ MyList ํด๋์ค๋ด GetEnumerator๋ก ์ง์
// 3. ์ ์ธ๋ ํ๋จ ์ฝ๋ ์คํ ํ ๋ค์ foreach ์ ์ด๋ถ๋ก ์ฌ๋ผ๊ฐ in์ ๋ง๋๋ฉด ์ด์ yield return๋ฌธ ๋ค์์ผ๋ก ๋ณต๊ท.
{
Console.WriteLine(item);
}
}
}
}
Output
1
2
3
4
5
yield
๋ฅผ ์ฌ์ฉํ๋ฉดIEnumerable
,IEnumerator
๋ฅผ ์์๋ฐ๋ ํด๋์ค๋ฅผ ์์ฑํด ์ค ํ์ ์๋ค.IEnumerable
ํด๋์ค์์GetEnumerator()
๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ํ ๋ฐฉ๋ฒ์ผ๋กyield
๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ฆ,GetEnumerator()
๋ฉ์๋์์yield return
๋ฅผ ์ฌ์ฉํ์ฌ ์ปฌ๋ ์ ๋ฐ์ดํ๋ฅผ ์์ฐจ์ ์ผ๋ก ํ๋์ฉ ๋๊ฒจ์ฃผ๋ ์ฝ๋๋ฅผ ๊ตฌํํ๊ณ , ๋ฆฌํดํ์ ์ผ๋กIEnumerator
์ธํฐํ์ด์ค๋ฅผ ๋ฆฌํดํ ์ ์๋ค.- C#์์ Iterator ๋ฐฉ์์ผ๋ก yield ๋ฅผ ์ฌ์ฉํ๋ฉด, ๋ช ์์ ์ผ๋ก ๋ณ๋์ Enumerator ํด๋์ค๋ฅผ ์์ฑํ ํ์๊ฐ ์๋ค. ์ปดํ์ผ๋ฌ๊ฐ ์์์ ๋ง๋ค์ด์ฃผ๊ธฐ ๋๋ฌธ์ด๋ค.
๋น๋๊ธฐ์ ์คํ์ด ๊ฐ๋ฅ
yield return
๋ฌธ์ ๋ง๋๋ฉด ํจ์๋ฅผ ํธ์ถํ ๊ณณ์ ๋ฆฌํด์ ํด์ค ํ ๋ค์ ๋์์์ ๋ค์yield return
๋ฌธ์ ์คํํ๋ค. ์ฆ, ํ๋์ ํจ์๋ฅผ ๋ชจ๋ ์คํํ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด ์๋๋ผyield
๋ฅผ ๋ง๋๋ฉด ์ ์ ํจ์ ์ค๊ฐ์ ๋น ์ ธ๋์ ํธ์ถํ ๊ณณ์ ๋ฆฌํด ๊ฐ์ ์ ๋ฌํด์ฃผ๊ณ ๋ค์ ๋์์ ๋ง์ ํจ์๋ฅผ ์งํํ๋ ์์ผ๋ก ์๋ค ๊ฐ๋ค ํ๋ฉฐ ์คํ๋๋ ๊ฒ์ด๋ค.
Enumerator
: ๋ฐ์ดํฐ ์์๋ฅผ ํ๋์ฉ ๋ฆฌํดํ๋ ๊ธฐ๋ฅ์ ํ๋ ๊ฒ.- ์์ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํด์ C# ๋๋ .Net์์๋ IEnumerator๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ค.
IEnumerator
๋Current(์์ฑ)
,MoveNext()(๋ฉ์๋)
,Reset()(๋ฉ์๋)
3๊ฐ์ ๋ฉค๋ฒ๋ก ์ด๋ฃจ์ด์ ธ์๋ค.- ๋ฐ๋ผ์,
Enumerator
๊ฐ ๋๊ธฐ์ํด์๋Current(์์ฑ)
,MoveNext()(๋ฉ์๋)
๋ฅผ ๋ฐ๋์ ๊ตฌํํด์ค์ผ ํ๋ค.
- ๋ฐ๋ผ์,
์ปฌ๋ ์ ํด๋์ค๋
Enumeration
์ด ๊ฐ๋ฅํ ํด๋์ค์ธ๋ฐ, ์ด๋ฌํ ํด๋์ค๋ค์Enumerable
ํด๋์ค๋ผ๊ณ ํ๋ค.- ์ด
Enumerable
ํด๋์ค๋IEnumerable
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผํ๋ค.
- ์ด
IEnumerable
์ธํฐํ์ด์ค๋GetEnumerator()
๋ฉ์๋ ํ๋๋ฅผ ๊ฐ์ง๊ณ ์๋ค.- ์ด๋
GetEnumerator()
๋ฉ์๋๋IEnumerator
๋ฅผ ๊ตฌํํ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํด์ค๋ค.
- ์ด๋
์ปฌ๋ ์ ํ์ ์ด๋ ๋๋ Enumerable ํด๋์ค์์
GetEnumerator()
๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ผ๋กyield
ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.GetEnumerator()
๋ฉ์๋์์yield return
์ ์ฌ์ฉํ๋ฉด ์ปฌ๋ ์ ๋ฐ์ดํฐ๋ฅผ ์์ฐจ์ ์ผ๋ก ํ๋์ฉ ๋๊ฒจ์ฃผ๋ ์ฝ๋๋ฅผ ๊ตฌํํ ์ ์๊ณ , ๋ฆฌํดํ์ ์IEnumerator
์ธํฐํ์ด์ค๋ฅผ ๋ฆฌํดํ ์ ์๋ค.
yield๋ฅผ ์ฌ์ฉํ๋ฉด ์ข์ ๊ฒฝ์ฐ.
- ๋ง์ฝ ๋ฐ์ดํ์ ์์ด ์ปค์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ฒ์ ๋ฆฌํดํ๊ธฐ ๋ณด๋ค ์กฐ๊ธ์ฉ ๋ฆฌํดํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ผ ๊ฒฝ์ฐ.
- ์๋ฅผ ๋ค์ด, ์ด๋ค ๊ฒ์์์ 1๋ง ๊ฐ์ ์๋ฃ๊ฐ ์กด์ฌํ๋๋ฐ, UI์์ 10๊ฐ์ฉ๋ง On Demand๋ก ํ์ํด ์ฃผ๋๊ฒ ์ข์ ์๋ ์๋ค. ์ฆ, ์ฌ์ฉ์๊ฐ 20๊ฐ๋ฅผ ์ํ ์ง, 1000๊ฐ๋ฅผ ์ํ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์, ์ผ์ข
์
์ง์ฐ ์คํ(Lazy Operation)
์ ์ํํ๋ ๊ฒ์ด ๋์ ์ ์๋ค.
- ์๋ฅผ ๋ค์ด, ์ด๋ค ๊ฒ์์์ 1๋ง ๊ฐ์ ์๋ฃ๊ฐ ์กด์ฌํ๋๋ฐ, UI์์ 10๊ฐ์ฉ๋ง On Demand๋ก ํ์ํด ์ฃผ๋๊ฒ ์ข์ ์๋ ์๋ค. ์ฆ, ์ฌ์ฉ์๊ฐ 20๊ฐ๋ฅผ ์ํ ์ง, 1000๊ฐ๋ฅผ ์ํ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์, ์ผ์ข
์
- ์ด๋ค ๋ฉ์๋๊ฐ ๋ฌด์ ํ์ ๋ฐ์ดํ๋ฅผ ๋ฆฌํดํ ๊ฒฝ์ฐ.
- ์๋ฅผ ๋ค์ด, ๋๋ค ์ซ์๋ฅผ ๋ฌด์ ํ ๊ณ์ ๋ฆฌํดํ๋ ํจ์๋ ๊ฒฐ๊ตญ ์ ์ฒด ๋ฆฌ์คํธ๋ฅผ ๋ฆฌํดํ ์ ์๊ธฐ ๋๋ฌธ์ yield ๋ฅผ ์ฌ์ฉํด์ ๊ตฌํํ๊ฒ ๋๋ค.
- ๋ชจ๋ ๋ฐ์ดํ๋ฅผ ๋ฏธ๋ฆฌ ๊ณ์ฐํ๋ฉด ์๋๊ฐ ๋๋ ค์ ๊ทธ๋ ๊ทธ๋ On Demand๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ข์ ๊ฒฝ์ฐ.
- ์๋ฅผ ๋ค์ด ์์(Prime Number)๋ฅผ ๊ณ์ ๋ฆฌํดํ๋ ํจ์์ ๊ฒฝ์ฐ, ์์ ์ ์ฒด๋ฅผ ๊ตฌํ๋ฉด (๋ฌผ๋ก ๋ฌด์ ํ์ ๋ฐ์ดํ๋ฅผ ๋ฆฌํดํ๋ ๊ฒฝ์ฐ์ด๊ธฐ๋ ํ์ง๋ง) ์๊ฐ์ ๋ง์ ๊ณ์ฐ ์๊ฐ์ด ์์๋๋ฏ๋ก ๋ค์ ์์๋ง ๋ฆฌํดํ๋ ํจ์๋ฅผ ๋ง๋ค์ด ์์ ์๊ฐ์ ๋ถ์ฐํ๋
์ง์ฐ ๊ณ์ฐ(Lazy Calculation)
์ ๊ตฌํํ ์ ์๋ค.
- ์๋ฅผ ๋ค์ด ์์(Prime Number)๋ฅผ ๊ณ์ ๋ฆฌํดํ๋ ํจ์์ ๊ฒฝ์ฐ, ์์ ์ ์ฒด๋ฅผ ๊ตฌํ๋ฉด (๋ฌผ๋ก ๋ฌด์ ํ์ ๋ฐ์ดํ๋ฅผ ๋ฆฌํดํ๋ ๊ฒฝ์ฐ์ด๊ธฐ๋ ํ์ง๋ง) ์๊ฐ์ ๋ง์ ๊ณ์ฐ ์๊ฐ์ด ์์๋๋ฏ๋ก ๋ค์ ์์๋ง ๋ฆฌํดํ๋ ํจ์๋ฅผ ๋ง๋ค์ด ์์ ์๊ฐ์ ๋ถ์ฐํ๋
yield์ ์์ธ
yield return
๋ฌธ์ try-catch
๋ฌธ ์์์ ์ธ ์ ์๋ค.yield break
๋ฌธ์ try-catch
๋ฌธ ์์์ ์ธ ์ ์์ง๋ง finally
์์ ์ธ ์ ์๋ค.
์ต์ข ์ ๋ฆฌ
- foreach๋ฌธ์ ํตํด ์ํํ๊ณ ์ถ๋ค๋ฉด ํด๋น ์๋ฃ๊ตฌ์กฐ ํ์
(์ฌ๊ธฐ์ ํด๋์ค?)์ด GetEnumerator() ๋ฉ์๋๋ฅผ ํฌํจํด์ผํ๋ค.
- ์ด๋ GetEnumerator์ ๋ฐํ ํ์ ์ IEnumerator()์ธ๋ฐ ์ด๋ Current ์ MoveNext()๋ฅผ ํฌํจํ๊ธฐ ๋๋ฌธ์ด๋ค.
- ์ฆ, ์ฌ์ฉ์๊ฐ ๋ณ๋๋ก Current์ MoveNext()๋ฅผ ์ ์ธํ ํด๋์ค๊ฐ ์๋ค๋ฉด ํด๋น ํด๋์คํ์ ์ ์ฌ์ฉํ์ฌ ๋ฐํํด๋ ๋๋ค.
Ex :
public class Computer
{
List<Device> _parts;
public Computer()
{
_parts = new List<Device>()
{
new Device() { Name = "CPU"},
new Device() { Name = "MotherBoard"},
};
}
public Device[] GetDevices()
{
return _parts.ToArray();
}
public IEnumerator<Device> GetEnumerator()
{
foreach (var device in GetDevices())
{
yield return device;
}
}
}
//////////////////IEnumerator ํ์
๋ฐํ์์
public class Computer
{
List<Device> _parts;
public Computer()
{
_parts = new List<Device>()
{
new Device() { Name = "CPU"},
new Device() { Name = "MotherBoard"},
};
}
public Device[] GetDevices()
{
return _parts.ToArray();
}
public PartList GetEnumerator()
{
return new PartList(this);
}
public class PartList
{
Device [] _devices;
public PartList(Computer computer) { _devices = computer.GetDevices(); }
int _current = -1;
public Device Current
{
get { return _devices[_current]; }
}
public bool MoveNext()
{
if (_current >= _devices.Length - 1)
{
return false;
}
_current++;
return true;
}
}
}
////////////////////////์ฌ์ฉ์ ์ ์ ํด๋์ค ํ์
๋ฐํ์์
- ์ถ๊ฐ์ ์ผ๋ก ๊ธฐ์กด ์ ์๋ IEnumerator ํด๋์ค์ IEnumerable ํด๋์ค๋ฅผ ์์๋ฐ์๋ ๋๋ค!
[Reference] : https://www.sysnet.pe.kr/2/0/12403
=> IEnumerable, IEnumerator ๋ด์ฉ ์ฐธ๊ณ
[Reference] : https://ansohxxn.github.io/c%20sharp/enumerate/
=> yield & IEnumerable, IEnumerator ๋ด์ฉ ์ฐธ๊ณ
'๐ป Programming Language > C#' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
26. ์ ๋ค๋ฆญ์ค(Generics) ํ์ ์ ์ฝ (0) | 2022.04.07 |
---|---|
25. ์ ๋ค๋ฆญ์ค(Generics) (0) | 2022.04.07 |
23. ์ปฌ๋ ์ ์ด๊ธฐํ, ์ธ๋ฑ์ (0) | 2022.04.07 |
22. Queue, Stack, Hashtable ์ฌ์ฉ (0) | 2022.04.07 |
21. ArrayList ์ฌ์ฉํ๊ธฐ (0) | 2022.04.07 |