공부/C#

(5) C# 기초 문법 - 연산자 오버로딩, foreach, 이터레이터, 가변배열 등

샤샤샤샤 2024. 10. 17. 21:51

1. 연산자 오버로딩
C#에서는 +, -, /, *, % 와 같은 연산자를 오버로딩 할 수 있다. 이를 이용하면 기본형이 아니여서 계산이 안되는 타입 역시 계산하는 것처럼 표현할수 있다. 객체를 선언하지 않고 일반 연산자처럼 사용하기 위해서 static 으로 선언해두는 것이 좋다.

public [static] 반환타입 operator [+, -, /, *, %] (매개변수1, 매개변수2) {}

이런 식으로 선언할 수 있다.

class Car
{
    public string name;
    public string maker;

    public Car(string name, string maker)
    {
        this.name = name;
        this.maker = maker;
    }

    public static Car operator +(Car car1, Car car2)
    {
        return new Car( car1.name,  car2.maker);
    }
}

 

 

이 코드는 + 연산자를 오버로딩을 통해 + Car 타입에서 + 연산자를 사용 가능하게 만든 것이다.

        Car car1 = new Car("벤츠", "메르세데스");
        Car car2 = new Car("현대", "아반떼");
        Car MixedCar = car1 + car2;
        Console.WriteLine("{0}, {1}", MixedCar.name, MixedCar.maker); // 결과 : 벤츠, 아반떼

 

2. foreach
C# 은 foreach 문을 지원하며, 이때 이를 이용해서 다차원 배열, 등을 모두 하나의 foreach 문을 통해 추가적인 코드 없이도 조회할 수 있다. 순환을 간단하게 만든 C# 의 강력한 문법이다.

       int[,] DoubleArr = { { 1, 2, 3 }, { 3, 4, 5 }, { 6, 7, 8 } };
       foreach (var item in DoubleArr)
       {
           Console.WriteLine(item);
       }

이때 순서대로 모든 요소가 출력된다.


3. 이터레이터
배열과 컬렉션 형태의 데이터를 반복적으로 꺼내는데 사용 가능하다.
IEnumerable 인터페이스를 상속받아 구현 가능하다. .Net 2.0 이상부터 yeild 키워드를 이용해서 쉽게 만드는 기능을 지원하고 있다. 

 -yeild 를 안쓰고 구현한 이터레이터

class Program
{
    static void Main()
    {
        // GenerateNumbers 메서드를 호출하여 생성된 숫자를 순회하며 출력합니다.
        foreach (int number in new NumberEnumerator().GetEnumerator())
        {
            Console.WriteLine(number);
        }
    }
}

// 커스텀 이터레이터 클래스로, IEnumerable<int>와 IEnumerator<int>를 구현합니다.
class NumberEnumerator : IEnumerable<int>, IEnumerator<int>
{
    // 이터레이션의 현재 값을 의미하는 변수입니다.
    private int _position = -1;

    // IEnumerator<T> 인터페이스의 현재 프로퍼티(property)입니다.
    // 현재 위치에 해당하는 값을 반환합니다.
    public int Current
    {
        get
        {
            // 현재 위치(_position)에 따라 다른 값을 반환합니다.
            switch (_position)
            {
                case 0: return 1;
                case 1: return 2;
                case 2: return 3;
                default: throw new InvalidOperationException();
            }
        }
    }

    // 비제네릭 IEnumerator 인터페이스의 Current 속성입니다.
    // 제네릭 Current 속성을 사용하여 값을 반환합니다.
   object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }
    
    // MoveNext 메서드는 이터레이터가 다음 위치로 이동할 수 있는지 여부를 반환합니다.
    public bool MoveNext()
    {
        _position++; // 위치를 증가시킵니다.
        return (_position < 3); // 위치가 3 미만일 경우 true, 그렇지 않으면 false를 반환합니다.
    }

    // Reset 메서드는 이터레이터의 위치를 초기화합니다.
    public void Reset()
    {
        _position = -1; // 위치를 -1로 설정하여 초기 상태로 되돌립니다.
    }

    // IEnumerable<T> 인터페이스의 GetEnumerator 메서드입니다.
    // 현재 객체를 반환하여 이터레이션을 지원합니다.
    public IEnumerator<int> GetEnumerator()
    {
        return this;
    }

    // 비제네릭 IEnumerable 인터페이스의 GetEnumerator 메서드입니다.
    // 제네릭 버전의 GetEnumerator 메서드를 호출합니다.
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

직접 구현하기 귀찮아서 gtp 의 도움을 받았다.

-yeild를 사용한 이터레이터

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        foreach (int number in GenerateNumbers())
        {
            Console.WriteLine(number);
        }
    }

    static IEnumerable<int> GenerateNumbers()
    {
        yield return 1;
        yield return 2;
        yield return 3;
    }
}

 

코드로 볼 수 있 듯 yeild 를 사용하는 것이 훨씬 간단하다. 

 

4. 가변배열
C#은 다차원 배열말고도 가변 배열을 지원한다. 비교해서 설명하자면 다차원 배열은 직사각형, 다차원 배열은 다각형이다. 그림으로 표현하면 다음과 같다.

- 2차원 배열
[][][]
[][][]
[][][]
[][][]

- 가변 배열
[][][][][]
[]
[][][]
[][]

즉, 가변배열은 하위 차원의 배열 길이가 자유로운 배열이다. 다차원 배열과 가변 배열의 선언 방식은 아래와 같다.

        int[,] doubleArr = new int[5,3];   // 5*3의 이차원 배열
        int[][] jaggedArr = new int[4][];  // 4개의 하위 배열을 가지는 가변 배열