컴퓨터/C#

| 니앙팽이 - C# | 2 | 참조 전달 [Ref & Out]

씨샵

🧑🏻‍💻 2. 메서드 매개 변수

함수의 Output은 꼭 Return으로 받지 않아도 된다.

매개 변수 인자가 리턴값이 된다면 어떻게 생각하나?

static void SetValueRef(ref string str) {
  str = "refString";
}

static void Main(string[] args)
{
  string str1 = "initString";
  Console.WriteLine("SetValueRef 메소드 호출 전: {0}", str1);
  SetValueRef(ref str1);
  Console.WriteLine("SetValueRef 메소드 호출 후: {0}\n", str1);
}

결과는 다음과 같다.

>   SetValueRef 메소드 호출 전: initString
    SetValueRef 메소드 호출 후: refString

📄 1. 용어 정리

1). ref, out

함수내에서 인수를 전달하는데 값 형식 참조로 전달되는 인수를 나타냄
Call By Reference : 리턴이 없는 함수라도, 인풋이 되고 아웃풋이 가능하게 만드는 테크닉으로 사용 가능하다.
매개변수를 통해 넣고 매개변수를 통해 받아오고 싶을때.

① 특징

차이점 ref out
초기화 여부 전달 되기전 초기화 필요
int num = 10
선언만 해도 됨
int num;
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public class Csharp_StringDeepCopy : MonoBehaviour {
    /************************************************************
    *
    * Int
    *
    ************************************************************/
    
    void IntByReference(int[] _Nums) {
        _Nums = new int[] {1,2,3,44,5,6,6,7,8,9};
        /*
        5 24 1 6 7 2 7 23 7 9 1 
        */
        
        //_Nums[0] = 1; _Nums[1] = 2; _Nums[2] = 3; _Nums[3] = 44; _Nums[4] = 5; _Nums[5] = 6; _Nums[6] = 6; _Nums[7] = 7; _Nums[8] = 8; _Nums[9] = 9;
        
        /*
        1 2 3 44 5 6 6 7 8 9 1 
    
        Csharp_NonGeneric:Start () (at Assets/Project_Csharp/Scripts/Csharp_NonGeneric.cs:67)
        */
    }

    /************************************************************
    *
    * String
    *
    ************************************************************/
    
    #region String
    
    string origin = "abcdef";
    public void ChageString(string _input) {
        _input = "1235";
    }

    public string StringReturn(string _input) {
        string ret = _input;
        ret = "6789";
        return ret;
    }
    public string StringReturnDirect(string _input) {
        // _input[0] = '6';
        // _input[1] = '7';
        // _input[2] = '8';
        // _input[3] = '9';
        //Readonly 라서 값 대입이 안된다.
        return _input;
    }
    
    #endregion

    /************************************************************
    *
    * Char Array
    *
    ************************************************************/
    
    #region CharArray

    char[] charOrigin = new char[] {'a','b','c','d', 'e'};

    public void ChangeCharArr(char[] _input) {
        _input = new char[] {'1', '2', '3', '4', '5'};
    }
    public char[] CharArrReturn(char[] _input) {
        char[] ret = _input;
        ret[0] = 'q'; ret[1] = 'w'; ret[2] = 'e'; ret[3] = 'r'; ret[4] = 't';
        return ret;
    }
    void PrintCharArray(char[] _arr){
        string ret = "";
        for(int i = 0 ; i < _arr.Length; i++){
            ret += _arr[i] + " ";
        }
        Debug.Log(ret);
    }
    #endregion

    /************************************************************
    *
    * Char List
    *
    ************************************************************/

    #region CharList

    List<char> charListOrigin = new List<char>() {'a','b','c','d', 'e'};

    public void ChangeCharList(List<char> _input) {
        _input = new List<char> {'1', '2', '3', '4', '5'};
    }
    public List<char> CharListReturn(List<char> _input) {
        List<char> ret = _input;
        ret[0] = 'q'; ret[1] = 'w'; ret[2] = 'e'; ret[3] = 'r'; ret[4] = 't';
        return ret;
    }
    void PrintCharList(List<char> _arr){
        string ret = "";
        for(int i = 0 ; i < _arr.Count; i++){
            ret += _arr[i] + " ";
        }
        Debug.Log(ret);
    }
    #endregion
    
    private void Start() {
        // Debug.Log(origin);                      //아마 abcdef         => abcdef
        // ChageString(origin);
        // Debug.Log(origin);                      //아마 1235 나올듯      => abcdef
        // Debug.Log(StringReturn(origin));        //아마 6789 나올듯      =>6789
        // Debug.Log(origin);                      //아마 6789 나올듯      =>abcdef

        /// 이말의 뜻은 참조 전달이 아닌 값 복사로 전달 되는것을 알 수 있음.
        /// Call By Value : DeepCopy
        /// Cpp이랑 비슷하다. &를 하냐 안하냐에 차이가 있다.

        // PrintCharArray(charOrigin);             //아마  a b c d e 나올듯 => a b c d e
        // ChangeCharArr(charOrigin);              
        // PrintCharArray(charOrigin);             //아마 1 2 3 4 5 나올듯 => a b c d e
        // PrintCharArray(
        //     CharArrReturn(charOrigin)
        // );                                      //아마  나올듯 => a b c d e
        // PrintCharArray(charOrigin);

        // 이 말의 뜻은 배열같은 경우 값 참조 전달로 된다는것을 알 수 있다.
        // Call By Reference

        PrintCharList(charListOrigin);          
        ChangeCharList(charListOrigin);
        PrintCharList(charListOrigin);

        PrintCharList(
            CharListReturn(charListOrigin)
        );
        PrintCharList(charListOrigin);

    }
}
/*
abcdef

abcdef

6789

abcdef
*/


/*
a b c d e 

a b c d e 

q w e r t 

q w e r t 
*/

/*
a b c d e

a b c d e

q w e r t

q w e r t
*/

참조

  1. https://daekyoulibrary.tistory.com/entry/C-참조에-의한-매개변수-전달-ref-out

  2. https://developer-talk.tistory.com/53

  3. https://codingcoding.tistory.com/56

  4. https://yeko90.tistory.com/entry/c-기초-ref-vs-out-차이