in 키워드
- in 매개변수로 전달되는 변수는 메서드로 전달되기 전 반드시 초기화
- 인수가 참조로 전달되지만, 수정되지 않음
- 오버로딩 규칙
class InOverloads
{
// 오버로딩 허용
public void SampleMethod(in int i) { }
public void SampleMethod(int i) { }
}
class CS0663_Example
{
// 오버로딩 미허용
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on in, ref and out".
public void SampleMethod(in int i) { }
public void SampleMethod(ref int i) { }
}
out 키워드
- out 매개변수로 전달되는 변수는 메서드로 전달되기 초기화할 필요 없음
- 그러나 메서드가 반환되기 전, 반드시 값을 할당
- 오버로딩 규칙
class OutOverloadExample
{
// 오버로딩 허용
public void SampleMethod(int i) { }
public void SampleMethod(out int i) => i = 5;
}
class CS0663_Example
{
// 오버로딩 미허용
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(out int i) { }
public void SampleMethod(ref int i) { }
}
ref 키워드
- 참조로 메서드에 인수 전달
- 메서드 정의와 호출 메서드가 모두 ref 키워드를 명시적으로 사용
void Method(ref int refArgument)
{
refArgument = refArgument + 44;
}
int number = 1;
Method(ref number);
Console.WriteLine(number);
// Output: 45
- 오버로딩 규칙
class RefOverloadExample
{
// 오버로딩 허용
public void SampleMethod(int i) { }
public void SampleMethod(ref int i) { }
}
테이블
키워드 |
읽기 |
쓰기 |
ref |
가능 |
가능 |
in |
가능 |
불가능 |
out |
가능 |
필수 |
params 키워드
- 가변 개수의 인수를 사용하는 메서드 매개 변수를 지정
- params 키워드 뒤에 다른 매개 변수를 추가할 수 없음
- 선언 형식은 1차원 array
- 사용 예시
public void UseParams(params int[] list)
{
// do something withe the list...
}
int Main()
{
// 지정된 형식의 쉼표로 구분된 인수 목록으로 호출
UseParams(1,2,3,4);
// 지정된 형식의 array로 호출
int [] a = {1,2,3,4,5};
UseParams(a);
}
참초 타입 인자
값으로 인자 넘기기
class PassingRefByVal
{
static void Change(int[] pArray)
{
pArray[0] = 888; // 이 할당은 원래 arr 데이터에 영향을 준다
pArray = new int[5] {-3, -1, -2, -3, -4}; // 이 할당은 로컬에 한정된다
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
}
static void Main()
{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]);
Change(arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
}
}
/* 결과:
Inside Main, before calling the method, the first element is: 1
Inside the method, the first element is: -3
Inside Main, after calling the method, the first element is: 888
*/
- 지역 변수로 새롭게 할당하려한 주소값은 스코프(Change 함수) 내에서만 유효하고, 그 밖에서는 그렇지 못했다
- 다만 직접 메모리에 접근해 값을 수정한 pArray[0] = 888;는 유효했다
참조로 인자 넘기기
class PassingRefByRef
{
static void Change(ref int[] pArray)
{
// 아래 할당은 모두 arr 데이터에 영향을 준다
pArray[0] = 888;
pArray = new int[5] {-3, -1, -2, -3, -4};
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
}
static void Main()
{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]);
Change(ref arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
}
}
/* Output:
Inside Main, before calling the method, the first element is: 1
Inside the method, the first element is: -3
Inside Main, after calling the method, the first element is: -3
*/
- ref로 넘긴 참조형의 인자는 스코프 내에서도 모두 값이 변화한다
Unity에서 Vector3의 값 변경하기
transform.position.x = 10f; // 안 바뀜
transform.position.SetX(10f); // 안 바뀜
transform.posiiton = new Vector3(10f, 0f, 0f); // 바뀜
// ????
- 위와 같은 일이 많았다
- 우선, transform.position은 gettor, 즉 read-only다
- 아무리 값을 변경하려고 해도 그 copy에 값을 할당하고 있을 뿐이다.
직접 접근하고 싶다면, position[0], position[1], position[2]로 접근할 수 있다안 되던데???
- 그럼 transform.position의 Set은?
- 그럼 다른 방법은?
// 값을 복사해서 다시 할당하거나
var pos = transform.position;
pos.y = 1f;
transform.position = pos;
// 아예 새로 할당하거나
transform.position = new Vector3(1f, 1f, 1f);
Vector3 position { get; set; }
- =operator에 의해 set이 발동했기 때문
출처