회차
[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 프로필정보를 통해 문의 바랍니다.

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

정은성 드림

Posted by LenAWeb

댓글을 달아 주세요

  1. 인연은 우연히 찾아오고 사랑은 조심스럽게, 몰래 찾아온다.

    2013.04.07 23:44 [ ADDR : EDIT/ DEL : REPLY ]
  2. 그들은 화려한되지 않기 때문에 어떤 사람들은 대단하지 않을 지출하지만, 자신의 마음이 멋진 아이디어를 스쳐하지 않았기 때문에, 또는 얼마나 영리 모르겠어요.

    2013.04.08 22:07 [ ADDR : EDIT/ DEL : REPLY ]
  3. http://www.xn--6ck2bwcu74pofcq24aotk,Topics related articles:


    http://visionandlogic.net/340 复件 (13) 韩

    .com/
    http://www,Topics related articles:


    http://game1112.tistory.com/128 复件 (16) 韩

    .lisseurghdle,Topics related articles:


    http://december08.tistory.com/m/post/view/id/612 复件 (11) 韩

    .com/

    2013.04.21 09:48 [ ADDR : EDIT/ DEL : REPLY ]
  4. http://www.saclongchampxl,Topics related articles:


    http://www.blue2sky.com/780 复件 (17) 韩

    .com/
    http://www,Topics related articles:


    http://myipcam.kr/973 复件 (11) 韩

    .nikeairmaxfrse,Topics related articles:


    http://naturalstyle.kr/?page=21 复件 (19) 韩

    .com/

    2013.04.21 18:25 [ ADDR : EDIT/ DEL : REPLY ]
  5. 귀를 기울여봐 가슴이 뛰는 소리가 들리면 네가 사랑하는 그 사람 널 사랑하고 있는거야.

    2013.04.23 14:46 [ ADDR : EDIT/ DEL : REPLY ]
  6. 지금은 반짝반짝 빛이 나겠지,, 하지만 시간이 흐르면 그빛은 사라저버릴거야,지금 우리처럼

    2013.07.17 03:25 [ ADDR : EDIT/ DEL : REPLY ]

 회차
[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

04| Dynamic 유형 객체 #2 : Dynamic lookup
말 못할 일상생활에 빠져 포스팅이 늦어버렸네요. 흑흑..어쨌든 프로젝트 투입전까지 포스팅을 마무리 짓겠습니다.

오늘 다뤄볼 내용은 바로 Dynamic lookup인데요. Dynamic lookup과 함께 C# 4.0에서 가장 큰 변화라고 하면 바로 Dynamic 키워드 도입이라고 할수 있습니다. 이번 포스팅에서는 Dynamic이 어떤 의미를 가지고 있고 Dynamic lookup을 통해 duck Typing의 프로그래밍 스타일에 대해 알아보도록 하는 시간을 가져보도록 하겠습니다.


Dynamic에 대해서 생각을 해보시면 무언가 굉장히 추상적이다 라는 의미를 알 수 있습니다.
C# 4.0의 PM인 Mads Torgersen이 기술한 New Features in C# 내용을 인용한다면 다음과 정의 할 수 있습니다.

- The Dynamic Type
- Dynamic Operations
- Runtime Lookup
   가. COM objects(COM IDispatch)
   나. Dynamic Objects
        (IDynamicObject, IronPython, IronRuby, HTML DOM)
- Plain object(.NET object reflection etc)

위 표를 보시면 동적 유형, 동적 연산, 런타입 룩업, 일반 개체로 나누어져 있습니다.
이번 포스팅에서는 전부 살펴볼수 없기에 그 중동적 유형, 동적 연산, 런타임 룩업에 대해서 살펴보도록 하겠습니다.

* 동적 유형(Dynamic Type)

C# 4.0에서 새로운 정적 타입의 동적 키워드를 소개를 하고 있습니다. 동적 유형의 오브젝트를 사용할 때는 런타임 에서만 그 타입을 결정 할 수 있는데요. 먼저 코드를 살펴보도록 하겠습니다.

[코드 1] Dynamic Type Sample
dynamic d = GetDynamicObject(...);
d.M(7);

겉모습으로 볼때 반환하는 메소드 형태와 큰 차이는 없어 보입니다. 그러나 이미 여기서 코드를 보시면서 의문을 가지신분들이 계실것 같은데요. 바로 dynamic 키워드와 GetDynamicObject 메소드의 관계가 굉장히 의심 스럽습니다.
GetDynamicObject 이름을 가진 메소드는 어떤 타입을 가지고 반환하는지 알수가 없을 뿐만 아니라 dynamic이라는 키워드의 변수에 할당하는 모습이 예사롭지 않다는 사실을 알수 있습니다.

C# 4.0 컴파일에서는 GetDynamicObject 메소드와 같이 어떤 이름과 어떤 인수를 가진 메소드든 간에 동적 타입에게 할당할 경우 허용을 하고 있습니다. 이유는 dynamic 형식은 정적 형식이지만 정적형식 검사에서 제외됩니다.

이형식의 타입을 사용하는 개체에서 값을 가져오는 소스가 COM API, Ironpython과 같은 동적언어, DOM 개체모델 등 프로그램 내부인지 다른 위치인지 또는 리플렉션이라도 신경 쓰지 않으셔도 됩니다.
여기서 동적 타입 개체는 바로 d인데요.
개체 d는 어떤 메소드를 호출 하려고 액션을 취하고 있습니다.
앞서 말씀을 드렸듯이 동적 유형의 오브젝트를 사용할때에는 런타임에서만 그 타입을 결정을 할수 있기 때문에 컴파일 시점에는 알수는 없습니다. 결국 런타임시점에서 d는 M에 관련된 가장 적합한 메소드를 찾게 되며 매개변수로 전달되는 심볼 유형이 숫자이기때문에 int형 매개변수를 가진 메소드를 호출하게 됩니다.


그래도 이해가 되지 않으셨다면 간단한 예제 코드를 살펴보시면 이해가 될것 같네요.

[코드 2] Dynamic Type Sample
dynamic d = 7;
int i = d;

위 코드는 [코드 1]의 d.M(7); 코드 구문을 이해 하고자 간단한 코드를 보였는데요.
dynamic d = 7 수식 같은경우 RValue인 숫자 심볼 7을 LValue인 Dynamic d 변수에 할당하는 모습입니다.
이는 컴파일 타임에서 암시적으로 int형 타입으로 캐스팅하는 행위로 재해석할수 있습니다.

int i = d 수식은 위 수식과 달리 런타임에서 동적타입인 d 변수에 대해서 암시적으로 int형으로 캐스팅이 되어집니다.

* 동적 조작(Dynamic Operations)
Method 호출 뿐만 아니라, Field 접근, Indexer 및 Operator 호출, Constructor 호출, 대리자 형식까지 동적으로 재정의할 수 있습니다.다음 코드를 보시면 동적 조작에 대한 예제에 대해 알수 있습니다.

[코드 3] Dynamic Operations Sample
dynamic d = GetDynamicObject(...);
d.M(7);                         // Method 호출의 예
d.f = d.P;                       // 해당 Field/Property에 대해 Getter/Setter의 예
d["one"] = d["two"];       // Indexer의 예
int i = d + 3;                   // Operator 호출의 예
string s = d(5,7);            // Delegate를 통해 호출의 예
var c = new C(d);          // Constructor 호출의 예

C# 컴파일러의 역할은 단순히 "무엇을 동적"으로 수행되는지에 대해 필요한 정보를 패키지할 뿐만 아니라 런타임에서 그정보가 무엇의 정확한 의미를 가지는지 실제 개체를 동적으로 부여됩니다.

* Dynamic 뭐가 좋아?
그럼 dynamic 키워드가 뭐가 좋은데? 라고 질문을 주실 수 있는데요. 하위 버전의 C# 코드와 비교 해보겠습니다.
[코드 4] Dynamic Sample
[코드 4-1] 정적 타입 유추
Calculator calc = new Calculator();
int sum = calc.Add(10, 20);

[코드 4-2] 컴파일 타입 유추
var calc2 = new Calculator();
int sum2 = calc2.Add(10, 20);

[코드 4-3] 런타임 타입 유추
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);

첫번째 코드[코드 4-1]는 가장 일반적인 정적 타입 유추 코드이며 두번째[코드 4-2] var 키워드의 특징을 이용하여 존재하지 않지만 컴파일 타임에서 Calculator라는 클래스임을 판단하여 타입을 유추를 하게 되고 해당 두 숫자를 합하여 sum varable에 값을 반환을 하게 됩니다. 세번째 코드[코드 4-3]에서는 dynamic 타입을 사용하였는데요 dynamic 타입은 실행시간을 지연하여 런타임에서 타입을 유추를 하게 됩니다. 처음 Dynamic 에 대해서 설명을 드렸듯이 정적타입 검사에서 Add라는 메서드는 제외가 되므로 런타임에서 바인딩 되어 동적으로 호출합니다.

여기서 만약에 dynamic 키워드가 없다면 어땠을까요?

dynamic  키워드가 없었다면 다음과 같이 작성을 해야합니다.
[코드 5] Reflection Sample
object calc = GetCalculator();
Type calcType = calc.GetType();
object res =  calcType.InvokeMember("Add", BindingFlags.InvokeMethod,                      
                                                        null, new object[] { 10, 20 }); int sum = Convert.ToInt32(res);

GetCalculator 클래스가 다른 외부의 객체 모델(Object Model) 은 아니지만 외부 객체라고 가정을 해보겠습니다.
근데 성능상 좋지는 않아보입니다. 왜냐하면 Variant를 위해 불필요하게 object 형식을 다시 해당하는 타입으로 cast을 하고 있는데요. 이는 오버헤드를 발생하게됩니다. 더구나 코드도 어렵네요.

여러분이 객관적으로 보실 때 선택을 한다면 reflection을 사용하시겠습니까?
아니면 dynamic 키워드를 사용하시겠습니까?

이번 포스팅에서 두 특징에 대해서 상세히 다를 순 없지만 간단히 설명을 드리자면 속도면에서 사실상 리플렉션이 더 빠른 결과를 나타내고 있습니다. 그리고 dynamic은 리플렉션에 비해 느리지만 리플렉션의 단점이였던 많은 메모리 소모와 호환성 문제를 높은 수준으로 보장하고 있습니다

여러분들의 코드에 동적으로 무언가를 꼭 해야 한다면 필요한 시점에서 사용하시기를 권장합니다.

* Duck Typing(dynamic lookup)
Dynamic 키워드를 도입을 하면서 dynamic lookup이라는 말과 함께 새로운 동적 프로그래밍 스타일이 이슈가 되었는데요
바로 Duck Typing 이라는 프로그래밍 스타일이 C#에서 가능하게 되었습니다.

위키디피아에서 다음과 같이 정의가 되어 있습니다.
If it walks like a duck and quacks like a duck, I would call it a duck



위 문장을 인용을 한다면 오리처럼 행동하면 오리라 부를 수 있다는 의미로써,
문자열처럼 다루게 된다면 그것이 객체이든 뭐든 상관하지 않고 그객체를 문자열처럼
취급해도 된다라는 이야기입니다.

흔히 알고 있는 상속이나 구현과 같이 해당 객체의 부모나, 인터페이스의 영향아닌 그 오브젝트가 가진 특징에 의해 역활을 결정 되는거죠.

즉, Duck Typing과 같이 룩업을 하게 된다면 어떤 클래스나 인터페이스 타입의 오브젝트인지에 상관없이 호출시 해당 오브젝트 존재하기만하면 사용 할 수 있습니다.





* Dynamic Lookup과 함께 Duck Typing 스타일이 이슈가 된 이유?

어떤 어플리케이션을 만들고 테스트를 해야할 때 일반적으로 mock오브젝트를 만들고 테스트를 하죠? 자바와 같은 Static Typing 언어에서는 mock object를 만들기 위해서 실제 사용할 오브젝트와 동일한 인터페이스를 구현을 해야 합니다. 다형성을 활용하여 구현을 할 수 있지만 만약 인터페이스 내에 메소드가 많다면 테스트와 관계없는 메소드까지 구현을 해야 한다는 단점이 있습니다. 다행히 IDE의 도움으로 쉽게 생성을 할 수 있지만 한 메소드를 테스트하기 위해서 모든 메소드를 구현을 해야한다면 좋지 않겠죠? 정말 비효율적인데요. 이런 바탕으로 프로그래밍 스타일이 이슈가 되게 되었습니다.

다음 데모를 보시면서 " Dynamic Lookup이 이렇게 사용하는구나! " 라고 이해가 될것 같네요.

[코드 6] Dynamic Lookup Sample
var people = new { Name = "정은성", Age = 27 };
PeopleInfo(people);

public static void PeopleInfo(dynamic d)
{
      Console.WriteLine( "이름: {0}, 나이: {1}" , d.Name, d.Age);
}

코드 6번과 동일한 퍼포먼스를 수행하기 위해서는 리플렉션을 이용하거나 해당 매개변수와 동일한 인터페이스를 가지거나 멤버변수를 지정을 해줘야만 PeopleInfo 메소드를 수행을 할수 있었습니다. Dynamic 도입으로 인해 늦은 바인딩이 가능한 모습을 볼수 있습니다. 다음 데모를 통해 Duck Typing에 대해서 더 많은 이해를 할 수 있습니다.

[코드 7] ExpandoObject Sample
      class Program {
        static void Main(string[] args) {
            dynamic people = new ExpandoObject();
            people.Name = "정은성";
            people.Age = new Sameple();      //new Sameple();  or  27
            people.Run = new Action(() => Console.WriteLine("Run 메소드 런타임에서 실행 "));
            printInfo(people);
            people.Run();
        }
        static void printInfo(dynamic info) {
            Console.WriteLine(string.Format("이름{0}, 나이는 {1} 입니다.", info.Name, info.Age));        }
    }
    class Sameple    {
        private int Age = 27;
        public override string ToString() {
            return this.Age.ToString(); }
    }

다음 코드 좀 주목해야할 부분입니다.
people.Age = new Sameple();      //new Sameple();  or  27
일반적인 코드라면 동일한 타입이 아닌 이상 오류가 날수 밖에 없는데요.
C# 4.0에서는 Dynamic Lookup 가능하기 때문에 런타임에서 수행가능한 코드라면 그것이
숫자든 문자열든 관계없이 수행을 할수 있습니다.

people.Run = new Action(() => Console.WriteLine("Run 메소드 런타임에서 실행 "));
람다 문장을 활용하여 해당 메소드를 룩업한 모습을 볼수 있습니다.

[코드 8] IronPython Sample ( ※ DevDays2010에서 선보였던 예제코드를 재구성 )
ScriptRuntime py = Python.CreateRuntime();
dynamic python = py.UseFile("Calculator.py");
dynamic calc = python.GetCalculator();

for (int i = 0; i < 10; i++)
{
    var sum = calc.Add(DateTime.Today, TimeSpan.FromDays(i)); 
    Console.WriteLine(sum);    
}

[소스 참고]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. dynamic(C# 참조)
    :
http://msdn.microsoft.com/ko-kr/library/dd264741.aspx
3. The Dynamic Keyword in C# 4.0 - CodeProject
    : http://www.codeproject.com/KB/cs/TheDynamicKeyword.aspx
4. BOO -Duck Typing
    : http://boo.codehaus.org/Duck%2BTyping


포스팅을 마치며...
맨날 바쁘다며 포스팅을 게으르게 올리고 있는데요. 열심히 하겠습니다. 흑흑..

Dynamic Lookup에 관한 포스팅은 여기까지 하도록 하겠습니다.
더 궁금하신점이 있으시면 댓글 혹은 http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.

다음 회차에서는 Optional and Named Parmeters에 대해서 살펴보도록 하겠습니다.
무더위 준비 잘하시고 좋은 하루 되세요 : )
감사합니다.

정은성 드림

Posted by LenAWeb

댓글을 달아 주세요

  1. 매우 지원, 아주 좋아, http://ntu.bottesuggdt.com chaussures ugg.

    2013.04.13 18:39 [ ADDR : EDIT/ DEL : REPLY ]
  2. 희미한 달빛이 샘물 위에 떠있으면,나는 너를 생각한다.

    2013.07.15 07:16 [ ADDR : EDIT/ DEL : REPLY ]