ice rabbit programming

[C#] 메소드 본문

Development/C#

[C#] 메소드

판교토끼 2020. 5. 4. 02:24

이번 글에서는 Method, 메소드에 대해서 알아보자. C/C++에서 Function, 함수라고 부르는 것과 동일한 개념인데 C#에서는 명칭을 Method라고 한다. 실제 사용하는 분들께 들어보면 함수라는 용어와 메소드라는 용어를 혼용하는 것 같다. 보통은 같은 것을 가리킨다. 이 글은 C# 내용이므로 메소드 용어를 사용하겠다. 

메소드는 타 언어와 유사하게 반환 타입, 이름, 인자, 내용으로 구성된다.

public int Sum(int num1, int num2) {
	return num1+num2;
}

일반적인 메소드(함수)에 대한 내용은 생략하도록 하고, C#의 메소드에 대해서 좀 더 알아보자.

ref, out

인자에서 ref라는 키워드를 사용할 수 있다. Value Type에서 ref 키워드를 사용하면 참조 형식으로 쓸 수 있다. C++에서 &를 붙여서 넘기는 것과 비슷하다.

이런 개념을 이용해 반환 값을 여러 개 받고 싶을 때 사용하는 out 키워드도 있다.

public int Foo(int num1, int num2, out int result) {
	result=num1+num2; // 연산 결과 전달
    return 0; // 성공 의미 전달
}

//Main에서
int result=0;
int isSuccess = Foo(num1, num2, result);
//result에는 10이 담긴다.

ref와 write 모두 Call by Reference로 동작하고 ref는 read와 write가 모두 가능하며, out은 write만 가능하다는 차이가 있다.
다만 애초에 Reference type일 경우에는 Call by Reference로 동작한다. 단 헷갈리면 안 되는게, 참조 변수 자체는 stack에 있는 Call by Value이므로 메소드 내부에서 new로 새 객체를 할당하면 다른 객체를 가리키게 된다.

가변 길이 매개변수

변수의 개수가 여러 개인데 유동적일 때는 배열로 전달한다.

params int[] arr 과 같은 배열을 인자로 사용하고, 여러 타입을 전달하고 싶을 때는 object로 지정해주면 된다. C#의 모든 객체는 object인 특징을 이용한 것이다.
단, 몇 개는 지정하고 몇 개는 정해지지 않은 타입으로 받고 싶다면 아래와 같이 혼합으로 적용할 수 있다.

public int sum(int num1, int num2, params object[] arr)

위처럼 혼합해서 사용할 경우에는 마지막 인자에만 가변 길이를 사용할 수 있다.

Named, Optional 매개변수

메소드는 기본적으로 나열된 순서대로 인자가 들어가는데, 호출하는 측에서 Named 매개변수를 사용하면 순서대로 넣지 않고 이름을 부여할 수 있다.

SetRect(x: 10, y: 20, width: 30, height: 40);
SetRect(10,20,width:30,height:40); // 앞은 x와 y로 알아서 들어간다.

보통은 선언부와 호출부의 인자 순서를 맞추기 때문에 많이 쓰는 개념은 아니지만 알고 있으면 유용할 듯하다.

Optional 매개변수는 C++의 default parameter와 같은 개념으로, 인자가 들어오지 않았을 시에 기본값을 지정하는 것이다. 가변 길이와 같이 뒤에서부터 적용해야 하며, 컴파일 타임에 알 수 있는 값(상수)만 초기값으로 활용 가능하다. 런타임에 정해지거나 property는 사용할 수 없다.

public int sum(int num1=0, int num2=0)
{
	// num1, num2가 인자로 넘어왔다면 해당 값
    // 비었다면 0으로 기본값
	reutn num1+num2;
}

확장 메소드(Extension Method)

이 개념은 C#을 하면서 처음 알았다. 기존 클래스를 건들지 않고 새로운 메서드를 해당 클래스에 추가하는 개념이다(다른 클래스가 아니니 상속과는 다르다).

class Car {
	private int speed;
    public void Go(){} // 원래는 Go(Car this)와 같이 동작
}
static class CarExtension {
	public static void Stop(this Car c) {}
}

//Main에서
Car c = new Car();
c.Stop; // CarExtension의 Stop이 호출

객체의 메소드를 호출할 때 본인 객체를 인자로 넣을 수 있다는 점을 이용한 것이다. 원래 Car의 Go 메소드도 본인 객체를 첫 인자로 가져오는 것인데, 생략되어 표현되는 것이다. 그렇기 때문에 Stop에서 현재 객체 Car를 인자로 받기 때문에, Car 객체는 c에서 Stop을 호출할 수 있는 것이다.

자료형, 배열에 이어서 이번에는 메소드에 대해서 정리해 보았다. 다음에는 Property에 대해서 정리해보겠다.

'Development > C#' 카테고리의 다른 글

[C#] Index와 Range  (0) 2020.05.17
[C#] Property와 Indexer  (0) 2020.05.10
[C#] 배열(Array)  (0) 2020.04.30
[C#] C#의 자료형3 - Casting과 Boxing  (0) 2020.04.18
[C#] C#의 자료형2 - Value vs Reference, Nullable  (2) 2020.04.15