Priv's Blog

foreach( ) 문과 참조 타입 본문

Dev. Study Note/Unity

foreach( ) 문과 참조 타입

Priv 2023. 11. 5. 22:47


 

 

1. foreach( ) 문

foreach( ) 문은 배열이나 리스트, 딕셔너리 등과 같은 타입의 인스턴스를 매개변수로 받아서 각 요소들을 반복적으로 반환하는 편리한 반복문입니다.

var fibNumbers = new List<int> { 0, 1, 1, 2, 3, 5, 8, 13 };
foreach (int element in fibNumbers)
{
    Console.Write($"{element} ");
}
// Output:
// 0 1 1 2 3 5 8 13

하지만 foreach( ) 문은 enumerator를 사용합니다.

다른 언어에서는 iterator라는 단어를 사용하지만, C#에서는 enumerator라는 단어를 사용하므로 구분해 사용하겠습니다.

 


 

2. enumerator는 참조 형식(Reference Type)입니다.

데이터를 다루는 형식에는 값 형식(Value Type)과 참조 형식(Reference Type)이 있습니다.

값 형식은 할당된 메모리 주소에 실제 값이 저장됩니다.

변수가 대표적인 값 형식입니다.

C#에서 객체를 다룰 때 흔히 보게 되는 키워드, new가 사용되면 인스턴스화가 이루어집니다.

이렇게 만들어진 인스턴스는 참조 형식입니다.

참조 형식은 해당 인스턴스가 저장된 메모리 주소를 '참조'하는 주소가 메모리에 저장됩니다.

즉, 참조 형식은 구조상 인스턴스가 가지고 있는 실제 값을 건드릴 수가 없습니다.

그러므로 아래 코드는 에러를 발생시킵니다.

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public enum StatusType {
    STAMINA,
    BODY_HEAT,
    HYDRATION,
    CALORIES
}

public class Player : MonoBehaviour {
    public static Player Instance;

    public Dictionary<StatusType, int> Status { get; private set; }

    
    private void Init() {
        if (Instance != null) {
            return;
        }
        
        Instance = this;

        this.Status = new Dictionary<StatusType, int>();
        
        this.Status.Add(StatusType.STAMINA, 100);
        this.Status.Add(StatusType.BODY_HEAT, 100);
        this.Status.Add(StatusType.CALORIES, 100);
        this.Status.Add(StatusType.HYDRATION, 100);
    }

    private void Awake() {
        Init();
    }

    public void StatusUpdate(int value) {
        foreach (KeyValuePair<StatusType, int> VARIABLE in this.Status) {
            VARIABLE.Value += value;
        }
    }
}

참조 타입이기 때문에 StatusUpdate( ) 메서드에서 사용된 VARIABLE.Value += value;는 실행될 수 없습니다.

다만 참조 타입이어도 값을 읽어오는 것은 가능하므로, VARIALBE.Value를 콘솔에 출력하는 코드는 문제없이 실행될 것입니다.

위 코드를 올바르게 수정하면 다음과 같습니다.

    public void StatusUpdate(int value) {
        foreach (var VARIABLE in this.Status) {
            Debug.Log(VARIABLE.Value);
        }
        
        for (int i = 0; i < this.Status.Count; i++) {
            this.Status[(StatusType)i] += value;
        }

        foreach (var VARIABLE in this.Status) {
            Debug.Log(VARIABLE.Value);
        }
    }

 


 


수고하셨습니다!


Comments