메서드 한 줄은 네 부분으로 되어 있다
Esc

    메서드 한 줄은 네 부분으로 되어 있다

    –C#기초

    세 사람의 평균 점수를 구하는 코드를 씁니다.

    int sum1 = a1 + b1 + c1;
    double avg1 = sum1 / 3.0;
    Console.WriteLine(avg1);
    
    int sum2 = a2 + b2 + c2;
    double avg2 = sum2 / 3.0;
    Console.WriteLine(avg2);

    같은 코드가 두 번 나왔습니다. 반이 셋이면 세 번입니다.

    문제는 길이가 아니라 고칠 때입니다. 평균을 소수점 한 자리까지만 보여주기로 하면 세 군데를 고쳐야 하고, 한 군데를 빠뜨리면 화면에 두 가지 모양이 섞여 나옵니다. 그리고 이 코드 덩어리가 무엇을 하는 것인지는 읽어 봐야 압니다.

    한 덩어리에 이름을 붙여 두고 이름으로 부르는 것이 메서드입니다.

    메서드는 이렇게 생겼다

    double Average ( int a, int b ) { ... } 돌려줄 값의 타입 이름. 부를 때 쓴다 받을 것. 매개변수 무슨 일을 하는가. 본문
    돌려줄 것, 이름, 받을 것, 하는 일. 네 부분이 전부다.
    double Average(int a, int b, int c)
    {
        int sum = a + b + c;
        return sum / 3.0;
    }
    • double 이 메서드가 돌려줄 값의 타입입니다.
    • Average 가 이름입니다. 이 이름으로 부릅니다.
    • 괄호 안이 받을 것입니다. 여기 적은 것을 매개변수라고 합니다.
    • 중괄호 안이 하는 일입니다.
    • return 이 값을 돌려주는 자리입니다.

    기계 한 대라고 보면 됩니다. 재료를 넣으면 결과가 나옵니다. 쓰는 쪽은 안에서 무슨 일이 벌어지는지 몰라도 됩니다. 이름과 투입구, 배출구만 알면 씁니다.

    앞의 코드를 다시 쓰면 이렇습니다.

    Console.WriteLine(Average(a1, b1, c1));
    Console.WriteLine(Average(a2, b2, c2));

    이제 고칠 자리가 한 곳입니다. 그리고 Average 라는 이름이 무엇을 하는지 말해 줍니다.

    정의는 만들어 두는 것, 호출은 돌리는 것

    메서드를 적어 두기만 하면 아무 일도 일어나지 않습니다. 적어 두는 것을 정의, 실제로 부르는 것을 호출이라고 합니다.

    이게 앞에서 본 선언과 할당의 관계와 닮았습니다. 정의는 “이런 기계가 있다” 고 적어 두는 것이고, 실행되는 것은 호출할 때입니다.

    호출하면 흐름이 어떻게 움직이는지 보겠습니다.

    부른 자리로 돌아옵니다. 이게 중요합니다. 메서드는 위에서 아래로 흘러가는 코드를 잠깐 다른 데로 보냈다가 제자리로 데려옵니다. 갈라지기도 되돌아가기도 아닌 세 번째 움직임입니다.

    호출한 자리에는 돌려받은 값이 남습니다. 그래서 Average(80, 90) 은 계산이 끝나고 나면 그냥 85 라는 값입니다. 앞에서 식은 값 하나로 줄어든다고 했는데, 메서드 호출도 식입니다.

    돌려줄 것이 없으면 void

    출력하고 끝나는 일에는 돌려줄 값이 없습니다. 이때 반환 타입 자리에 void 를 적습니다.

    void PrintLine()
    {
        Console.WriteLine("--------");
    }
    
    PrintLine();

    void 는 “돌려주는 것이 없다” 는 표시입니다. return 을 안 써도 됩니다.

    돌려주는 것이 없으니 값으로 쓸 수도 없습니다.

    int n = PrintLine();     // 컴파일 에러: void 는 값이 아닙니다

    Console.WriteLine 도 void 입니다. 그래서 그 결과를 변수에 담을 수 없습니다.

    이름은 하는 일로 짓는다

    메서드 이름은 무엇을 하는지가 드러나야 합니다. 그게 메서드를 쓰는 이유의 절반입니다.

    double Calc(int a, int b, int c)      // 무엇을 계산하는지 모릅니다
    double Average(int a, int b, int c)   // 평균이라는 것을 압니다

    C# 에서는 메서드 이름을 대문자로 시작합니다. 변수는 소문자로 시작합니다. 문법이 강제하는 것은 아니지만 거의 모든 코드가 이렇게 되어 있어서, 지키지 않으면 읽는 사람이 걸립니다.

    값을 돌려주는 메서드는 명사나 명사구로(Average, GetPrice), 하고 끝나는 메서드는 동사로(PrintLine, Save) 짓는 편이 읽힙니다.

    언제 메서드로 묶나

    같은 코드가 두 번 보이면 묶을 때가 된 것입니다. 이건 분명합니다.

    한 번밖에 안 쓰는 코드도 묶을 이유가 있습니다. 이름을 붙이려고 묶습니다.

    if (age >= 19 && !isStudent && hasTicket && !isBanned)

    앞에서 이 조건에 bool canEnter 라는 이름을 붙였습니다. 같은 이야기입니다. 긴 코드 덩어리에 이름을 붙이면 읽는 사람이 그 덩어리를 한 단어로 넘어갈 수 있습니다.

    정리

    • 메서드는 코드 덩어리에 이름을 붙여 두고 이름으로 부르는 것입니다.
    • 반환 타입, 이름, 매개변수, 본문 네 부분으로 되어 있습니다.
    • 정의는 적어 두는 것이고, 실행은 호출할 때 일어납니다.
    • 호출하면 그리로 갔다가 부른 자리로 돌아옵니다. 그 자리에 돌려받은 값이 남습니다.
    • 메서드 호출도 식입니다. 값 하나로 줄어듭니다.
    • 돌려줄 것이 없으면 void 입니다. 값으로 쓸 수 없습니다.
    • 같은 코드가 두 번 보이거나, 덩어리에 이름을 붙이고 싶을 때 묶습니다.