반응형
Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발꿈나무

[C# 교과서] 20. C# 활용(14) - 인덱서와 반복기 본문

C# 기초

[C# 교과서] 20. C# 활용(14) - 인덱서와 반복기

HYOKYE0NG 2022. 1. 20. 10:25
반응형
인덱서와 반복기

 

  • 인덱서: 클래스의 인스턴스를 배열처럼 사용할 수 있도록 하는 구문
  • 반복기: 컬렉션 항목을 단계별로 실행하는 데 사용하는 구문

 

인덱서

인덱서(indexer)는 속성 여러개를 하나로 표현하거나 개체를 배열 형식으로 표현할 때 사용한다.

배열의 인덱스 접근 방식인 개체이름[0], 개체이름[1] 식으로 개체 속성 또는 멤버에 접근할 수 있게 한다.

using System;

class Catalog
{
    //[1] 정수형 인덱서: this[int index] 형태로 정의되어 개체명[0], 개체명[1] 형태로 호출됨 
    public string this[int index]
    {
        get
        {
            return (index % 2 == 0) ? $"{index}: 짝수 반환" : $"{index}: 홀수 반환";
        }
    }
}

class IndexerNote
{
    static void Main()
    {
        Catalog catalog = new Catalog();
        Console.WriteLine(catalog[0]); //[2] 개체명[인덱스] 형태로 호출 가능
        Console.WriteLine(catalog[1]);
        Console.WriteLine(catalog[2]);
    }
}

/*
0: 짝수 반환
1: 홀수 반환
2: 짝수 반환
*/

인덱서는 속성과 달리 이름을 따로 지정하지 않고 this 키워드를 사용하며, 매개변수로 배열 형식을 받는다.

 

인덱스를 사용하여 여러 값 주고받기

using System;

namespace Indexer
{
    class Developer
    {
        private string name;
        // 인덱서 
        public string this[int index]
        {
            get { return name; }    // [index]로 요청시 특정 필드의 값을 반환한다.
            set { name = value; }   // 넘어온 값은 value 키워드로 읽어올 수 있다.
        }
    }

    class Indexer
    {
        static void Main()
        {
            var developers = new Developer();
            developers[0] = "홍길동"; // 인덱스와 상관없이 name 필드에 문자열이 저장된다. 
            Console.WriteLine(developers[0]); // 홍길동
            developers[1] = "백두산";
            Console.WriteLine(developers[1]); // 백두산
        }
    }
}

 

 

배열 형식의 필드를 사용하는 인덱서

using System;

namespace WeekDemo
{
    public class Week
    {
        //[1] 필드: 요일 문자열을 담아 놓을 수 있는 문자열 배열 
        private string[] _week; 

        //[2][1] 생성자: 매개 변수가 없는 생성자
        public Week()
        {
            Length = 7; // 기본값 초기화 
            _week = new string[Length]; // 7개의 요소를 갖는 배열 생성
        }
        //[2][2] 생성자: 매개 변수가 있는 생성자
        public Week(int length)
        {
            Length = length;
            _week = new string[Length]; 
        }

        //[3] 속성
        public int Length { get; }

        //[4] 인덱서: 개체를 배열 형태로 사용하도록 this[] 형태의 인덱서 생성 
        public string this[int index]
        {
            get { return _week[index]; }
            set { _week[index] = value; }
        }
    }

    class WeekDemo
    {
        static void Main()
        {
            //[A] 배열 형식 생성
            Week week = new Week(3);

            //[B] 인덱서로 문자열 값을 초기화
            week[0] = "일요일";
            week[1] = "월요일";
            week[2] = "화요일";

            //[C] 출력: 인덱서로 배열 형식의 필드값 출력 
            for (int i = 0; i < week.Length; i++)
            {
                Console.WriteLine($"{week[i]}");
            }
        }
    }
}

/*
일요일
월요일
화요일
*/

 

 

문자열 매개변수를 받는 인덱서 사용하기

// <NickName.cs>
using System.Collections;

namespace NickNameDemo
{
    public class NickName
    {
        //[1] 필드: 해시테이블 형식의 필드 생성 
        private Hashtable _names = new Hashtable();

        //[2] 인덱서: 문자열 매개 변수를 받고 문자열 값을 반환
        public string this[string key]
        {
            get { return _names[key].ToString(); }
            set { _names[key] = value; }
        }
    }
}



//<NickNameDemo.cs>
using System;

namespace NickNameDemo
{
    class NickNameDemo
    {
        static void Main()
        {
            //[A] NickName 클래스의 인스턴스(개체) 생성
            var nick = new NickName();

            //[B] 문자열 인덱서 사용
            nick["박용준"] = "RedPlus"; // Key와 Value 형태로 저장
            nick["김태영"] = "Taeyo";

            //[C] 문자열 인덱서 값 출력
            Console.WriteLine($"{nick["박용준"]}, {nick["김태영"]}");
        }
    }
}

 

 

 

반복기와 yield 키워드

반복기(iterator)는 배열과 컬렉션 형태의 데이터를 단계별로 실행하는 데 사용할 수 있다.

반복기를 구현할 때는 IEnumerable 인터페이스와 yield 키워드를 사용한다.

 

yield return을 사용하여 이터레이터 구현하기

using System;
using System.Collections;

class YieldReturn
{
    //[1] 반복기(이터레이터) 구현: MultiData() 메서드는 3번 반복해서 문자열이 반환됨
    static IEnumerable MultiData()
    {
        yield return "Hello";
        yield return "World";
        yield return "C#";
    }

    static void Main()
    {
        //[2] 반복기를 foreach 문으로 호출해서 사용 
        foreach (var item in MultiData())
        {
            Console.WriteLine(item);
        }
    }
}

[1] yield return 구문은 IEnumerable 인터페이스 형식으로 반환된다.

 

 

이터레이터를 사용하여 배열 값을 foreach 문으로 출력하기

using System;
using System.Collections;

namespace FavoriteLanguage
{
    public class Language
    {
        //[1] 필드
        private string[] languages;
        //[2] 생성자
        public Language(int length)
        {
            languages = new string[length];
        }
        //[3] 인덱서
        public string this[int index]
        {
            get { return languages[index]; }
            set { languages[index] = value; }
        }
        //[4] 반복기(이터레이터)
        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < languages.Length; i++)
            {
                yield return languages[i]; 
            }
        }
    }

    class FavoriteLanguage
    {
        static void Main()
        {
            //[A] 클래스의 인스턴스 생성 
            var language = new Language(2);

            //[B] 정수 형식의 인덱서로 문자열 값 저장
            language[0] = "C#";
            language[1] = "TypeScript";

            //[C] foreach 문을 사용하여 배열의 값을 출력 
            foreach (var lang in language)
            {
                Console.WriteLine(lang); 
            }
        }
    }
}

 

IEnumerable<T>로 컬렉션 형태의 데이터 반환받기

using System;
using System.Collections.Generic;

class YieldDescription
{
    static void Main()
    {
        int[] numbers = { 1, 2, 3, 4, 5 };

        foreach (var n in Greater1(numbers, 3))
        {
            Console.WriteLine(n);
        }

        foreach (var n in Greater2(numbers, 3))
        {
            Console.WriteLine(n);
        }
    }

    //[1] yield 사용 전: List<T> 형태의 컬렉션 클래스를 임시로 사용하여 결괏값 저장 후 반환
    static IEnumerable<int> Greater1(int[] numbers, int greater)
    {
        List<int> temp = new List<int>();
        foreach (var n in numbers)
        {
            if (n > greater)
            {
                temp.Add(n);
            }
        }
        return temp;
    }

    //[2] yield 사용 후: 추가적인 클래스 사용없이 여러 데이터를 yield return으로 반환
    static IEnumerable<int> Greater2(int[] numbers, int greater)
    {
        foreach (var n in numbers)
        {
            if (n > greater)
            {
                yield return n;
            }
        }
    }
}

 

 

 

 

 

<Reference>

 

반응형
Comments