C# ref 키워드
- ref 가 하는일ref 키워드를 이용하면 명시적으로 call by refence(참조 전달)을 할수있습니다정수 타입들은 기본적으로 매개변수로 보낼때 call by value값이 전달 되기 때문에
public void ChangeNum(int num) { num = 10; } int a = 99; ChangeNum(a); Console.WriteLine(a); // a는 그대로 입니다
- 전달하는 변수와의 관계가 끊어지게 된다
- 참조 전달을 하게되면 매게변수로 전달한 값의 원본이 변경이 된다
- 기본적으로 c# 메서드에 인자를 전달할때 call by value (값 전달)을 합니다.
a의 값 99를 전달 하더라도 ChangeNum에서 num 으로 매개변수를 받을 때 call by value 이기 때문에 문자 그대로 99만 전달이 된다
메서드 밖에 a 와 ChangeNum 내부에 있는 num은 관계가 없다
참조로 전달을 하면 해당 변수에 별칭이 생김
ref 키워드를 붙이면 call by reference가 된다
public void ChangeNum(ref int num)
{
num = 10;
}
int a = 99;
ChangeNum(ref a);
Console.WriteLine(a); // a는 10 입니다
이렇게 되면 변수 a 도 num도 동일한 변수를 나타내게 되고 함수 내부에서 값을 바꾸면
함수 밖에 있는 것도 영향을 주게 된다
**
참조를 전달 한 다는 것은 참조 형식과 개념이 다름
값 형식이 참조로 전달될 때 boxing 되지 않는다
그대로 전달된 매개변수에 별칭을 붙여서 해당 변수의 값을 변경하는 방식
참조 타입의 객체들 같은 경우에는 기본적으로 call by value 로 (ref 키워드를 붙이지 않고) 전달 하더라도 함수 내부에서 객체의 상태를 변경 할 수 있다 ( 함수 밖에 있는 객체에 영향을 줌)
명시적으로 전달하거나 객체 내부가 아닌 객체 자체를 변경할 수 도 있으므로 구분을 확실히 해서 ref 키워드를 붙여야함
- ref 사용법과 특징
ref의 경우 변수를 전달하기 전에 반드시 초기화가 되어있어야 한다
ref는 함수의 매개변수 앞 부분에서도 키워드를 작성 해주어야 하며 함수 호출시에도 ref 키워드를 붙여 주어야 한다
함수 선언시 매개 변수 앞에 ref 붙여줌
public void ExFunc(ref int num) { ... };
보낼 변수 초기화 필수
int a = 10;
함수 호출시 변수 앞에 ref 붙여줌
ExFunc(ref a);
C# ref 키워드 예제
- 값 타입 ref 비교
class MainApp
{
public static void ChangNumRef(ref int num)
{
num = 10;
}
public static void ChangeNumVal(int num)
{
num = 10;
}
public static void Main()
{
//값 타입
int a = 99;
int b = 99;
int c; // 초기화 하지 않은 변수
ChangNumVal(a); // call by value
ChangNumRef(ref b) // call by refence
// ChangNumRef(ref c); // ERROR : 초기화 하지 않은 변수는 ref로 넘길수 없습니다
Console.WriteLine($"a = {a}, b = {b}")
Console.WriteLine($"call by value 'a' : {a}");
Console.WriteLine($"call by reference 'b' : {b}");
}
}
위 예제같이 타입의 경우에는 ref 를 사용 하는 것 과 안 하는 것의 차이가 확실하다
ref를 붙이지 않는 경우에는 함수 밖에 있는 변수에 영향을 전혀 주지 않고
ref 를 붙이는 경우에 함수 밖에 있는 변수에 영향을 주게 된다
- 참조 타입 ref 비교
using System;;
namespace test
{
public class MyName
{
public int num = 10;
public string name = "test";
public void PrintAll()
{
Console.WriteLine($"num : {num}, name : {name}");
}
}
}
class MainApp
{
public static void ChangeVal(MyName myName)
{
Console.WriteLine("\\nCalled 'ChangeVal'....")'
myName.num = 111;
myName.name = "Value Name";
}
public static void ChangeRef(ref MyName myName)
{
Console.WriteLine("\\nCalled 'ChangeRef"....");
myName.num = 222;
myName.name = "Ref Name";
}
public static void Main()
{
// 참조 타입
MyName myName = new MyName();
myName.PrintAll(); // 선언 하자마자 확인
ChangeVal(myName);
myName.PrintAll(); // ref 선언 안하고 함수 호출후 확인
ChangeRef(ref myName);
myName.PrintAll(); // ref 함수 호출 후 확인
}
}
참조타입(class)는 ref 를 선언을 하던 하지 않던 함수 인자로 넘겨서 값을 변경하게 되면 함수 밖에 있는 것도 영향을 준다
- 참조 타입 객체 할당 ref 비교
using System;
namespace test
{
public class MyName
{
public int num;
public string name;
public void PrintAll();
{
Console.WriteLine($"num : {num}, name : {name}");
}
}
}
class MainApp
{
public static void ChangeVal(MyName innerMyName)
{
Console.WriteLine("\\nCalled'ChangeVal'....");
innerMyname = new MyName(111, "Value test"); // 새 객체 할당
}
public static void ChangeRef(ref Myname innerMyName)
{
Console.WriteLine("\\nCalled 'ChangeRef'...."); // 새 객체 할당
}
public static void Main()
{
Myname myName = new MyName(99, "test");
myName.PrintAll();
ChangeVal(myName);
myName.PrintAll();
ChangeRef(ref myName);
myName.PrintAll()
}
}
새로운 객체를 생성해서 연결을 할 때 참조 타입 에서 차이가 나게 됨
'개발일지 > C#' 카테고리의 다른 글
회계 관리 프로그램 예제 (1) | 2024.11.09 |
---|---|
인사 급여 관리 프로그램 예제 (0) | 2024.11.08 |
C# Delegate (2) | 2024.10.02 |
C# Indexer (0) | 2024.10.02 |
yield (5) | 2024.10.01 |