출처 : http://blog.tobegin.net/37  / Writer by 정은성

 

 회차
[C# 4.0] New Features in C# : 01. C# Programing Trend
[C# 4.0] New Features in C# : 02. C# 4.0 Overview
[C# 4.0] New Features in C# : 03. Dynamically Typed Objects #1 : DLR
[C# 4.0] New Features in C# : 04. Dynamically Typed Objects #2 : Dynamic Lookup
[C# 4.0] New Features in C# : 05. Optional and Named Parameters
[C# 4.0] New Features in C# : 06. Com-specific interop features
[C# 4.0] New Features in C# : 07. Covariance and Contravariance
 
05| 명명된 인수와 선택적 인수
 
(
Optional and Named Parameters)

구독자 여러분 안녕하세요
오랜만이시죠? ^^ 이제 저녁 온도가 제법 차가워지고 있네요.. 가을이 오려나봅니다.
건강에 유념하시길 바라구요 바로 포스팅 시작하도록 하겠습니다.

지난 시간에 이어서 오늘 다뤄볼 내용은 바로 명명된 인수와 선택적 인수(Optional and Named Parameters) 입니다. 누구나 개발을 하시다보면 종종 긴 파라미터를 정의를 해야할 때가 있는데요. 그 시그니처를 일치시키기 위해서 그 순서를 맞추려고 노력을 하거나 COM Interop에서 의미 없는 값을 전달을 하기 위해서 불필요한 코딩을 반복해왔습니다.

C# 4.0에서는 이러한 불필요한 코딩을 기본값을 설정을 하여 생략할 수 있게 개선이 되었는데요.
다음 예제 코드를 살펴보시면서 어떻게 개선이 되었는지 살펴보도록 하겠습니다.

[코드 1-1] Optional and Named Parameters Sample
public void M(int x, int y= 5, int z = 7) { ... }
1)  M(1, 2, 3);
2)  M(1, 2);
3)  M(1);

4)  M(1, z:3);
5)  M(x:1, z:3);
6)  M(z:3, x:1);


코드를 보시면 " 나는 저 코드와 유사하게 사용을해봤어 " 라고 생각을 하실분이 계씰것 같습니다.
구독자분들 중에 아이폰 어플리케이션을 개발을 해보신분이시거나 플렉스를 개발해본 경험이 있으시다면 바로 4~6번 코드와 같이 Named Parameter 방식으로 오브젝트를 활용을 해보신 경험이 있으실것 같습니다.

이기능은 두 언어로부터 유례된 것은 아니지만 앞서 소개해드린 Named Parameter,Optional parameter 방법이 개선이 되면서 어플리케이션 개발에 있어 코드 구성이 간결해지고 읽기 쉬운 코드를 작성이 가능해 졌습니다.

지금 부터 여러분들은 블록(색깔 블록)으로 처리한 부분을 유심히 살펴보실 보셔야합니다.
코드를 보시면 기존의 C# 코드와 다르게 매우 독특한 의미를 가지고 있는데요.

[코드 1-2] Optional and Named Parameters Sample
public void M(int x, int y= 5, int z = 7) { ... }

매소드 문장을 보시면 파라미터 타입을 정의하고 파라미터  이름인 int y와 int z에 5와 7의 숫자를 초기화하는 모습을 볼 수 있습니다. 기존에 볼 수 없었던 문장이지만 정의된 것과 같이 int y와 int z는 optional parameter를 정의하여 초기화 함으로써 옵셔널하게 그 매개변수나 메소드를 사용할 수 잇게 되었습니다. 무슨뜻이냐하면 일반적으로 객체를 생성하여 초기화 하거나 같은 이름을 가진 메소드를 정의를 할 수 있는데요. 보시는 코드와 같이 호출 지점에 대해서 컴파일을 하려고 할때 심덱스 에러가 나타나지 않으려고 한다면 같은 이름을 가진 메소드를 5번 정의를 해야합니다.

이제 부터는 Optional parameter를 활용하여 메소드가 5개 형태가 아니라
하나로 원하는 시그니처 만큼 표현이 가능해졌습니다.

[코드 1-3] Optional and Named Parameters Sample
public void M(int x, int y= 5, int z = 7) { ... }

1)  M(1, 2, 3);
2)  M(1, 2);
3)  M(1);


두번째 코드는 객관적으로 보실 때 가장 일반적인 메소드 형태 이거나 오버로딩이 가능한 메소드 형태들인데요. 원래는 각각의 시그너처 별로 메소드를 정의를 해야하는데요. 이것 또한 Optional Parameter방법을 정의 함으로써 매개변수를 생략을 할 수 있고 생략을 하더라도 매개변수의 값을 전달 할수 있습니다.

 [코드 1-4] Optional and Named Parameters Sample
public void M(int x, int y= 5, int z = 7) { ... }

4)  M(1, z:3);
5)  M(x:1, z:3);
6)  M(z:3, x:1);


마지막 코드를 보시면 파라미터 명칭에 무언가를 주입하려고 하고 있는데요
C# 4.0에서는 Named Parameter 방법이 지원을 함으로써 매개변수의 순서와 관계없이 데이터를 바인딩 할수 있게 되었습니다. 결과를 보시면서 알아보도록 하겠습니다.

[결과 1] Optional and Named Parameters
public void M(int x, int y= 5, int z = 7) { ... }
1)  M(1, 2, 3);              // 1, 2, 3
2)  M(1, 2);                 // 1, 2, 7
3)  M(1);                    // 1, 5, 7

4)  M(1, z:3);              // 1, 5, 3
5)  M(x:1, z:3);           // 1, 5, 3
6)  M(z:3, x:1);           // 1, 5, 3


이미 말씀 드린것과 같이 매개변수가 순서와 관계없이 데이터를 바인딩 할 수 있다고 말씀을 드렸습니다.
4~6번 코드는 매개변수 z와 x에 대해서 명시적으로 할당을 하고 있습니다. 그래서 결과는 위와 같습니다.

아직 이해를 하지 못하셨다면 또 다른 예제를 준비 하였는데요.
이번에는 구독자 분께서 컴파일러가 되어 어떤 호출을 할 때 어떤 메소드가 호출이 될지를 이해하고자 준비해보았습니다.
다음 예제코드를 보시면서 알아보도록 하죠.

[코드 2-1] Optional and Named Parameters
1)  M(String x , int y=1) { … }
2)  M(object x) { … }
3)  M(int x, string y= "hello") { … }
4)  M(int x) { … }


위 예제코드를 보시면 4가지 오버로딩이 가능한 후보들이 있습니다.
그리고 이때 Caller는 다음과 같습니다.

[코드 2-2] Optional and Named Parameters

호출 : M(5);

이제 컴파일러 입장에서 유추를 해봐야할 것 같은데요. 어떤 메소드가 어떻게 호출이 되어질까요?
제가 하나씩 풀이를 해보도록 하겠습니다.

1) 메소드는 y를 생략을 할수 있지만 x 타입과 일치하지 않기 때문에 후보 대상이 될 수 없습니다.
2) 메소드는 object 타입으로 데이터를 받아도 무방하기 때문에 후보가 됩니다.
3) 메소드는 x 타입과 매칭이 되고 y 매개변수는 생략이 가능하기 때문에 이것 또한 후보가 됩니다.
4) 메소드는 x타입과 매칭이 되기 때문에 후보가 됩니다.

다시 정리를 하자면 1) 메소드는 후보 대상이 될 수 없기 때문에 판단 기준에서 제외가 될것이며 2~4번 메소드 중에서 호출이 되어질텐데요. 가장 유력한 후보는 바로 4) 메소드입니다 이유는 타입이 가장 최적화된 시그니처를 가지고 있기 때문인데요.
2) 메소드는 Object로 받을수 있지만 Boxing / UnBoxing을 하기 때문에 성능상으로 좋아 보이지 않으므로 후보대상이지만 3~4번 메소드보다 좋지 않습니다. 3) 메소드는 Optinal parameter에 의해 생략이 가능하기 때문에 후보 대상이지만  아무래도 시그니처 패턴이 퍼펙트한 4번이 호출 될수 밖에 없습니다.

즉, 컴파일러는 호출하려고 하는 시점에서 파라미터가 온 결과를 보고 가장 최적화된 시그니처를 검사를 하게 됩니다. 만약 검사에서 성립이 되지 않으면 옵셔널 파라미터에 의해 메소드를 호출하게 됩니다.

정적 시그너처 체크 -> 옵셔널 파라미터 시그니처 체크 ->  동적타입 사용시 Runtime에서 해당 메소드 체크

Named and Optinal Parameters에서 단순히 코드를 줄여주는 역할 뿐만 아니라 가독성을 높여줍니다.
적절한 사례가 될지 모르겠지만 상황을 들어보도록 하겠습니다.

또와 둘리라는 개발자가 있습니다. 그리고 A라는 메소드를 공용으로 사용 해야한다고 가정을 하겠습니다. 마침 좀더 잘난 또치가 그 메소드를 디자인을 하게 되었는데요. 또치가 설계한 메소드의 매개변수로는 회원번호, 이름, 전화번호, 주민등록번호 순으로 구성을 하였습니다. 근데 둘리가 A라는 메소드를 사용을 할때 너무 코드가 들숙날숙하게 보여서 많이 불편했나봅니다. 둘리라는 개발자가 보는 관점에서는 주민등록번호를 먼저 사용을 해야 했기 때문에 코드가 작성에 가독성이 많이 떨어졌습니다. 그래서 수정을 요청을 했지만 또치가 보기에는 회원 번호가 우선적으로 표기가 되었어야 했습니다. 결국 불편하지만 둘리 개발자는 또치 개발자가 정의해둔 시그니처 패턴에 맞게 작성을 할 수 밖에 없었습니다. 

구독자 여러분들이 이 상황에서 어떻게 하시겠습니까? 당연히 Named Parameter 방법을 아셨으니깐 상황이 오신다면 시그니처를 변경하셔서 개발상에 전혀 문제 없이 즐거운 프로그래밍을 할수 있습니다.

그래도 너무 많이 남용하신다면 가독성이 떨어지기 때문에 필요한 시점에서만 사용하시기를 권장합니다.

와우!! 신기하지 않으신가요? 저 감탄까지 했어요 ^^

좀더 이해를 돕기 위해서 예제코드를 준비 해보았는데요.. 어떻게 사용하는지를 보시죠.

[코드 3] Optional and Named Parameters

namespace HelloFx4_3_NamedNOptionalParameters
{
    class Program
    {
        static void Main(string[] args)
        {
            People("정은성", 27, "남자");
            People("정은성", 27);
            People("정은성");
            People("정은성", Sex:"남자", Age:27);
        }

        private static void People(string Name, int Age = 27, string Sex = "남자")
        {
            Console.WriteLine(string.Format("이름은? {0}, 나이는? {1}, 성별은?{2}", Name, Age, Sex));
        }
    }
}



People메소드를 또 호출하려고 하는데. 코드를 작성하려고 하니깐 인첼리스트 기능에 메타정보가 나타나게 됩니다.

흔히 생략을 할 때 쓰는 중괄호가 보이는데요. 이제부터는 이 매개변수는 생략이 가능하고 생략을 한다면 묵시적으로 데이터가 전달 됩니다. 위 예제 코드는 매개변수를 옵셔널하게 정의를 해주며 생략이 가능한 모습을 보여드리기 위해서 짧게 다루어보았는데요. 다음 포스팅(Com-specific interop features)에서 혼합된 예제를 보여드리도록 하며 이번 포스팅을 마치도록 하겠습니다.

[소스 참고]Hello .NET Framework 4 세미나[세션3] 발표자료와 소스 : http://blog.tobegin.net/35

참고 문헌
1. PDC2008 : The Future of C# - Anders Hejlsberg
    :
http://channel9.msdn.com/pdc2008/TL16/

2. New Features in C# 4.0 - Mads Torgersen, C# Language PM, April 2010
    :
http://msdn.microsoft.com/ko-kr/vcsharp/ff628440(en-us).aspx
3. 명명된 인수와 선택적 인수(C# 프로그래밍 가이드)
    : http://msdn.microsoft.com/ko-kr/library/dd264739.aspx


포스팅을 마치며...

명명된 인수와 선택적 인수(Optional and Named Parameters) 포스팅 어떠셨나요?
이 기능 덕분에 코드가 심플해졌고 시그니처에 구해받지 않고 명명 할당이 가능해져서 기쁘네요 : )

다음회차에서는 COM 상호운용성(Com-specific interop features)에 대해서 다뤄볼 예정이며
COM 상호운용성 개선 사항 또한 오피스 프로그래밍을 자주 다뤄보신 분이라면 강력하다 라는 말을 하실겁니다.

더 궁금하신점이 있으시면 댓글 혹은
http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.

밤낮 기온이 점점 심해지고 있는데요 건강에 유념하시길 바라며 좋은 하루 되세요 : )
감사합니다.

정은성 드림
 
출처 : http://blog.tobegin.net/37  / Writer by 정은성
Posted by Sting!
,