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

07| 공변성과 반공변성(Covariance and Contravariance)
구독자 여러분 안녕하세요

오늘 다뤄볼 내용은 공변성과 반공변성입니다.
" 공변성, 반 공변성은 도대체 뭘까? "  Variance & ContraVariance 두단어를 볼 때 무슨 소리인지 알 수가 없을것입니다.


물론 수학을 많이 다뤄보셨다면 무슨 의미인지 알 수는 있지만 대부분의 개발자분들은 무심코 지나치셨거나 모른체 사용을 해왔을 것 같네요. 공변성, 반공변성은 수학에서 정의한 원리를 바탕으로 부모는 자식을 받아 드일수 있으나 자식은 부모를 받아 드릴 수 없는 원칙을 말하고 있습니다.


즉, 공변성은 원래 지정된 것 보다 더 많은 파생을 사용할수 있는 이며, 반공변성은 더 작은 파생 형식을 사용 할 수 있는 기능을 뜻합니다.

말이 어렵죠? 이해를 돕고자 일반적인 프로그래밍 이야기를 해보도록 하겠습니다. 클래스의 상속은 부모 클래스로부터 상속을 받아 메소드나 멤버 변수를 그대로 물려 받을 수 있을 텐데요.

자식은 양적으로 부모보다 더 많이 가지게 되며 반면에 부모클래스는 상속받은 자식과 비교를 한다면 적게 가진다는 결론을 내릴수 있습니다.

그렇다면 부모 클래스에 자식 클래스를 캐스팅 한다면 어떻게 될까요?

다형성 원칙에 의해 부모 클래스를 가지고 있는 기능을 제외한 추가된 자식의 기능은 무시가 되버리고 어쨌든 문제는 없어 보입니다. 반대로 자식을 부모에 대입하려고 한다면 형 변환에 대한 예외에러가 출력이 되겠죠. 지금부터 Genric covariance And Contra-Variance에 대해 설명을 하려면 그동안 어떻게 개선이 되고 있었는지 살펴보아야할것 같습니다.

* Variance in Arrays (C# 1.0)
C# 1.0에서부터 variance in Arrays라는 개념이 등장하게 되었습니다.

[코드 1] Variance in Arrays (C# 1.0) Sample
public class Animal { ... }
public class Lion : Animal { ... }
public class Deer : Animal { ... }
public class Cat : Animal { ... }

Animal[] animals = new Lion[3];
Animals[0] = new Deer();                      // Runtime시 Exception 발생

현재 보시는 코드는 전형적인 상속이 되는 코드입니다. 1.0에서는 위와 같이 Reference 타입을 할당하려고 할 때 covariance라고 하였습니다. Animal로 부터 상속  받은 사자와 사슴과 고양이는 Animal 스택틱 영역에  객체로 할당 할 수 있습니다.

여기서 살펴보셔야할 내용은 마지막 두번째 줄 코드인데요.
Animals 인스턴스에 사자를 할당을 하려고 하고 있는데. 이어서 마지막 코드에서 사자 우리에 사슴을 할당하려고 합니다.

일반적으로 사자 우리에 사슴을 넣으면 안되잖아요. 그럼 잡혀먹히잖아요...흑흑..ㅠㅠ


이처럼 C# 1.0 버전에서는 타입에 대한 불확실한 요소에 대해 보호 할 수 없었습니다. 

* Variance in Delegate-Member Association(C# 2.0)
그렇게 C# 2.0에서 제네릭과 대리자가 도입이 되면서 이전 버전의 불안정한 요소를 벗어 날 수 있게 되었습니다.
이들을 통해서 컴파일 타임에서 엄격한 체크가 수행이 되었고 안전한 코드를 작성 할 수 있게 되었습니다. 하지만 이때부터 공변성과 반공변성은 애매모한 관계를 가지게 되었죠.

코드를 보시면서 좀더 이해를 해보도록 하겠습니다.

[코드 2] Variance in Delegate-Member Association(C# 2.0) Sample
class Mammals { ... }
class Dogs : Mammals { ... }
public delegate Mammals HandlerMethod();
public static Mammals FirstHandler() { return null; }
public static Dogs SecondHandler() { return null; }

public Form1() {
             InitializeComponent();
 1)....   HandlerMethod handler = SecondHandler;
 2)....   this.textBox1.KeyDown += this.MultiHandler;
 3)....   this.button1.MouseClick += this.MultiHandler;

}
private void MultiHandler(object sender, System.EventArgs e) { ... }

현재 코드에서는 1번의 경우가 공변성이 되며, 2,3번의 경우는 반공변성이 되는 예제입니다.

* 1번의 경우
대리자를 사용한 경우입니다만 대리자 자신이 포함 할 수 있는 형식인 Mammals에 대해서만 해석을 할 수 가 있기 때문에 공변성 이락 할수 있습니다.

* 2,3번의 경우
이미 선언된 형식에 호환성을 맞추기 위해서 역으로 해석한 모습을 볼 수가 있는데요. EventArgs로부터 KeyEventArgs와 MouseEventArgs로 역으로 호환성을 맞추려고 하기 때문에 반공변성이 될 수 있습니다.

* Variance in Generic Delegate (C# 3.0)
그렇게 2.0에서 애모한 관계를 개선하고자 3.0이 등장을 하게 되었는데요.
이때는 제네렉과 대리자를 통해 공변성이 많이 지원이 되었습니다. 이말은 상위 클래스가 존재를 한다면 하위 클래스가 상위 클래스를 모두 가져 올 수 있도록 IEnumerable 인터페이스를 사용할수 있게 되어 covariance를 지원 하게 되었습니다.

지원을 하였지만 아래코드를 보시면 공변성에 대한 모순이 발생을 하게 되었습니다.
[코드 3] Variance in Generic Delegate (C# 3.0) Exception Sample
IList<string> strings = new List<string>();
IEnumberable<object> objects = strings;           ... 1)  // Exception 발생
var result = string.Union(objects);                    ... 2)  // Exception 발생


1번과 2번의 경우 공변성을 하려고 하는데 Exception이 발생되는 모습을 볼 수 있었습니다.

* Generic Covariance And Contra Variance(C# 4.0)
3.0에서 발생하게 된 이슈를 해결 하기 위해 4.0에서는 Generic Covariance And Contra Variance이 등장하게 됩니다.
코드를 보시면 새로운 형식을 볼 수 있을텐데요.

[코드 4] Generic Covariance And Contra Variance(C# 4.0) Sample
class Animal {}
class Cat : Animal { }
class Program
{
       delegate void ActionDemo<in T>(T a);
       delegate T FuncDemo<out T>();

        static void Main()
        {
                //Contra-Variance
                ActionDemo<Animal> act1 = (ani) => { Console.WriteLine(ani); };
                ActionDemo<Cat> cat1 = act1;
                cat1(new Cat());

                //CoVariance
                FuncDemo<Cat> cat = () => new Cat();
                FuncDemo<Animal> animal = cat;

                Console.WriteLine(animal());
        }
}

3.0에서 모순이 된 IEnumberable 인터페이스의 문제를 해결하면서 애모했던 공변성과 반공변성에 대해 새로운 형식인 IN, OUT 키워드를 도입하면서 관계를 해소 할 수 있게 되었습니다.

- Contra-Variance를 하시려면 IN 키워드를 사용
- Co-Variance를 하시려면 OUT 키워드를 사용

그외 인터페이스와 델리게이트는 다음과 같으며 자세한 사항은 MSDN 문서를 참고 바랍니다.

* InterFaces
- System.Collections.Generic.IEnumberable<out T>
- System.Collections.Generic.IEnumberator<out T>
- System.Linq.IQueryable<out T>
- System.Collections.Generic.IComparer<in T>
- System.Collections.Generic.IEqualityComparer<in T>
- System.IComparable<int T>

* Delegates
- System.Func<int T, ..., out R>
- System.Action<in T, ...>
- System.Predicate<in T>
- System.Comparison<in T>
- System.EventHandler<in T>

[소스 참고]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. 제네릭의 공변성(Covariance)과 반공변성(Contravariance)
    :
http://msdn.microsoft.com/ko-kr/library/dd799517.aspx


포스팅을 마치며...

유익한 포스팅이 되셨는지 모르겠네요.

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

정은성 드림

PS. 이번주는 태풍이 온다네요. 우산 꼭 챙기세요 ^ㅁ^
Posted by LenAWeb

댓글을 달아 주세요

  1. 아름다운 여자가 해바라기하는 걸 좋아해요

    2013.04.02 03:42 [ ADDR : EDIT/ DEL : REPLY ]
  2. 아름다운 여자가 해바라기하는 걸 좋아해요

    2013.04.03 03:19 [ ADDR : EDIT/ DEL : REPLY ]
  3. 사람들은 죽을걸 알면서도 살잖아 .사랑은 원래 유치한거에요

    2013.04.26 15:50 [ ADDR : EDIT/ DEL : REPLY ]
  4. 눈을 감아봐 입가에 미소가 떠오르면 네가 사랑하는 그 사람이 널 사랑하고 있는거야.

    2013.04.28 14:34 [ 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

06| COM특성 상호운용 개선사항
(
COM-Specific Interop. Improvements)

구독자 여러분 안녕하세요

이번 다뤄볼 내용은 바로 COM특성 어떻게 향상 되었는지 개선사항에 대해 알아보도록 하겠습니다.
COM은 소프트웨어 컴포넌트를 통합을 위해서 표준화된 인터페이스로  다양한 언어로 만들어 다른 소프트웨어와 공유를 할수 있도록 이진 레벨을 구성하고 있습니다. 대중화된 OS인 윈도우에서도 굉장히 많이 사용하고 있는데요.


흔히 오피스 오토메이션 프로그래밍을 할때 Office API에 관련된 PIA를 등록하여 실행 때마다 PIA에 맵핑되는 타입으로 형변환을 해주어야하며 성능상으로 좋지 않았습니다.

C# 4.0에서는 가져온 PIA 형식 정보 대신 포함된 형식 정보를 응용 프로그램에 포함시켜 배포를 할수 있게 되었습니다.
코드를 보시면서 살펴보도록 하겠습니다.

[코드 1] COM-Specific Interop Sample Fx4 이하
var missing = System.Type.Missing;
Excel.Workbook workBook =
                             excel.Workbooks.Open("filename.xlsx",  missing, missing, missing, missing,
                             missing, missing, missing, missing, missing, missing, missing, missing, missing,missing);             Excel.Worksheet workSheet =  (Excel.Worksheet)workBook.ActiveSheet;

 지금보시는 코드[코드 1]는 MS 오피스 프로그램의 오토메이션 되는 코드 조각입니다.
코드를 보시면 단순히 시트 하나를 Open 할 뿐인데 코드가 매우 복합한데다가 알 수 없는 타입과 함께 작성을 해줘야 하는 모습을 볼 수 있습니다. 전체 코드 작성된 기준으로 본다면 WorkSheet를 포함하여 ExcelApplication.WorkBook등 모두 기술을 했다면 코드가 생각보다 길어질것입니다.

또한 코드가 길어지는건 두번째로 볼때 코딩을 작성하다보면 도대체 이 인수가 어떻게 사용되는지 모를 뿐만 아니라 사용하지 않는 파라메터에 대해서는 ref 처리를 해줘야하는 불편한 개발을 할 수 밖에 없었는데요.
기존 VB개발자시라면 " 아 불편해!!! " 라고 생각이 드실겁니다.

그렇다면 Com 상호운용성이 어떻게 개선이 됬는지 확인 해보도록 하겠습니다.

[코드 2] COM-Specific Interop Sample Fx4
Excel.Workbook workBook = excel.Workbooks.Open("filename.xlsx“);
Excel.Worksheet workSheet =workBook.ActiveSheet;

와우 많고 불필요한 코드들이 단 두 줄로 줄어들었습니다. Option Parameters기능을 활용하여 정말 간소화 된 모습을 볼 수 있는데요. 어떤 내용들이 개선이 되었는지 스펙을 확인해보도록 하겠습니다.

* COM 상호 운용의 개선된 사항 
- Automatic Object -> dynamic mapping
- Optional and Named Parameters
- Indexed properties
- Optional “ref” modifier
- PIA embedding (“NO-PIA”)

COM 상호운용성이 위와 같이 개선이 되었습니다. 우선 Automatic Object 방법이 Dynamic mapping으로 변경이 되었고
Optional and named Parameters 기능이 지원함으로써 메소드가 간소화 된 모습을 볼수 있습니다.이 말은 이전에 사용하지 않던 매개변수에 대해서 ref missing을 처리를 해주었는데요. 이제는 사용을 안하셔도 된다는 이야기입니다. 그리고 기존의 오피스 프로그래밍을 하시다보면 PIA라는 인터페이스의 정의를 참조하여 호출을 하였고 어떤 인터페이스를 사용 할지 알수 없었기 때문에 형변환을 해줘야하는 지져분한 코드를 사용해야 만 했었고 더구나 성능상으로 좋지 않았습니다.

이제는 컴파일 타임에서 PIA를 직접적으로 사용하지 않으셔도 됩니다. PIA형식 정보를 응용프로그램에 포함 시키는 기능이 새롭게 추가 되었습니다. 즉, 해당 어셈블리에 대해서 옵션을 지정 할 수 있는데요.
Embed introp Type 을 지정해주므로써 필요한 PIA 인터페이스를 코드에 삽입하므로써 COM 객체와 좀더 퍼펙트한 상호 운용이 가능하게 되었습니다.

그럼 간단한 코드를 통해서 알아보도록 하겠습니다.

[코드 3] COM-Specific Interop Sample Fx4 이하
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

namespace HelloFx4_3_OfficeAutomaticSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var excel = new Excel.Application();
            excel.Workbooks.Add(Type.Missing);
            excel.Visible = true;
            ((Excel.Range)excel.Cells[1, 1]).Value2 = "Process Name";
            ((Excel.Range)excel.Cells[1, 2]).Value2 = "Memory Usage";
            var processes =
                    from p in Process.GetProcesses()
                    orderby p.WorkingSet64 descending
                    select p;
             int i = 2;
             foreach (var p in processes.Take(10))
            {
                ((Excel.Range)excel.Cells[i, 1]).Value2 = p.ProcessName;
                ((Excel.Range)excel.Cells[i, 2]).Value2 = p.WorkingSet64;
                i++;
            }
            Excel.Range range = (Excel.Range)excel.Cells[1, 1];
            Excel.Chart chart = (Excel.Chart)excel.ActiveWorkbook.Charts.Add(
                                                  Type.Missing, excel.ActiveSheet, Type.Missing, Type.Missing);             
            chart.ChartWizard(
                range.CurrentRegion,
                Type.Missing, Type.Missing, Type.Missing,
                Type.Missing, Type.Missing, Type.Missing,
                "Memory Usage in " + Environment.MachineName, Type.Missing,
                Type.Missing, Type.Missing);

                chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
                                           Excel.XlCopyPictureFormat.xlBitmap,
                                           Excel.XlPictureAppearance.xlScreen);
            var word = new Word.Application();
            word.Visible = true;
            var missing = Type.Missing;
            word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
            word.Selection.Paste();
        }
    }
}

[코드 3-1] (코드3) 코드 조각
var excel = new Excel.Application();
excel.Workbooks.Add(Type.Missing);
excel.Visible = true;

((Excel.Range)excel.Cells[1, 1]).Value2 = "Process Name";
((Excel.Range)excel.Cells[1, 2]).Value2 = "Memory Usage";


코드를 보시면 excelApplication를 인스턴스화 하여 위에 WorkBooks를 추가하였고 셀 1,1과 1,2에 문자열을 대입하였습니다. 

[코드 3-2] (코드3) 코드 조각
var processes =
    from p in Process.GetProcesses()
    orderby p.WorkingSet64 descending
    select p;
int i = 2;
foreach (var p in processes.Take(10))
{
    ((Excel.Range)excel.Cells[i, 1]).Value2 = p.ProcessName;
    ((Excel.Range)excel.Cells[i, 2]).Value2 = p.WorkingSet64;

    i++;
}

그리고 현재 컴퓨터의 운영중인 프로세스를 조회한 다음 링큐와 enumable 타입을 사용하여 각 셀에 바인딩하는 모습도 볼수 가 있습니다. 다음으로는 차트 생성 메소드를 활용하여 차트를 생성하고 새로운 워드 문서에 차트 이미지를 복사를 하는 데이터 플로우 입니다.

[코드 3-3] (코드3) 코드 조각
Excel.Chart chart = (Excel.Chart)excel.ActiveWorkbook.Charts.Add(
Type.Missing, excel.ActiveSheet, Type.Missing, Type.Missing);

chart.ChartWizard( range.CurrentRegion, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
"Memory Usage in " + Environment.MachineName, Type.Missing, Type.Missing, Type.Missing);

chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
      Excel.XlCopyPictureFormat.xlBitmap,
      Excel.XlPictureAppearance.xlScreen);

var word = new Word.Application();
word.Visible = true;
var missing = Type.Missing;
word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
word.Selection.Paste();

지금부터 개선된 특징을 적용 시켜야 할텐데요. 우선 그 대상이 무엇인지 살펴보면서 코드를 변경 해보도록 하겠습니다.
여러분들은 코드 3-1, 3-2, 3-3에서 블록 처리 되어 있는 코드를 살펴보시면 됩니다.

우선 [코드3-1]에 workbook에 Add 메소드에 매개변수가 그 변경 대상이 되며 다음으로는 형변환을 포함하여 Value2 프로퍼티가 변경 대상이 되며 다음과 같이 수정을 할 수 있습니다.

[코드 4-1] (코드 3-1)을 Fx4 특징으로 변경 
var excel = new Excel.Application();
excel.Workbooks.Add(Type.Missing);
excel.Workbooks.Add();
excel.Visible = true;

((Excel.Range)excel.Cells[1, 1]).Value2 = "Process Name";
((Excel.Range)excel.Cells[1, 2]).Value2 = "Memory Usage";

excel.Cells[1, 1].Value = "Process Name";
excel.Cells[1, 2].Value = "Memory Usage";


[코드3-2]에서 foreach문 내부의 range 부분도 또한 다음과 같이 수정이 가능합니다.

 [코드 4-2] (코드3-2)을 Fx4 특징으로 변경 
var processes =
    from p in Process.GetProcesses()
    orderby p.WorkingSet64 descending
    select p;
int i = 2;
foreach (var p in processes.Take(10))
{
    ((Excel.Range)excel.Cells[i, 1]).Value2 = p.ProcessName;
    ((Excel.Range)excel.Cells[i, 2]).Value2 = p.WorkingSet64;

    excel.Cells[i, 1].Value = p.ProcessName;
    excel.Cells[i, 2].Value = p.WorkingSet64;

    i++;
}

[코드3-3] 차트에서도 형변환을 포함하여 Add 메소드에 매개변수인  missing, activeSheet, Missing, Missing 인자들도 그 변경 대상이 됩니다. 표현하고자 하는 데이터는 두번째 매개변수이며 파라미터 명칭을 찾아보시면 After이름을 가졌네요.

[그림 1] (코드3-3) Charts.Add 인첼리스트

[코드 4-3] (코드3-3)을 Fx4 특징으로 변경
Excel.Chart chart = (Excel.Chart)excel.ActiveWorkbook.Charts.Add(
Type.Missing, excel.ActiveSheet, Type.Missing, Type.Missing);

Excel.Chart chart = excel.ActiveWorkbook.Charts.Add(After: excel.ActiveSheet);


코드를 다시 내려다 보시면 알수 없는 타입이 선언 되어 있는데요.
(Type.Missing, Type.Missing, Type.Missing, Type.Missing....)  이 코드 또한 변환 대상이 됩니다.

똑같이 적용을 해보면 다음과 같습니다.

[코드 4-4] (코드3-3)을 Fx4 특징으로 변경
chart.ChartWizard( range.CurrentRegion, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
"Memory Usage in " + Environment.MachineName, Type.Missing, Type.Missing, Type.Missing);
chart.ChartWizard(Source: range.CurrentRegion, Title: "Memory Usage in " + Environment.MachineName);

[그림 2] (코드3-3) chart.ChartWizard 인첼리스트



다시 아래 코드를 보시면 새로운 워드 문서를 추가하는 코드를 볼수 있습니다.
missing 타입을 ref 형태로 전달을 하기에 이것 또한 변경을 해줘야겠죠?

[코드 4-5] (코드3-3)을 Fx4 특징으로 변경
var word = new Word.Application();
word.Visible = true;
var missing = Type.Missing;
word.Documents.Add(ref missing, ref missing, ref missing, ref missing);

word.Documents.Add();

word.Selection.Paste();

이렇게 코드를 다시 정리를 해보면 다음과 같습니다.
[코드 5] COM-Specific Interop Sample Fx4
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

namespace HelloFx4_3_OfficeDynamicMappingSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var excel = new Excel.Application();
            excel.Workbooks.Add();
            excel.Visible = true;
            excel.Cells[1, 1].Value = "Process Name";
            excel.Cells[1, 2].Value = "Memory Usage";

            var processes =
                    from p in Process.GetProcesses()
                    orderby p.WorkingSet64 descending
                    select p;

            int i = 2;
            foreach (var p in processes.Take(10))
            {
                excel.Cells[i, 1].Value = p.ProcessName;
                excel.Cells[i, 2].Value = p.WorkingSet64;
                i++;
            }

            Excel.Range range = excel.Cells[1, 1];
            Excel.Chart chart = excel.ActiveWorkbook.Charts.Add(After: excel.ActiveSheet);

            chart.ChartWizard(Source: range.CurrentRegion, Title: "Memory Usage in " + Environment.MachineName);

            chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
                   Excel.XlCopyPictureFormat.xlBitmap,
                   Excel.XlPictureAppearance.xlScreen);

            var word = new Word.Application();
            word.Visible = true;

            word.Documents.Add();
            word.Selection.Paste();
        }
    }
}

정리를 하였지만 아직 PIA 인터페이스를 응용 프로그램에 포함시키지 않았습니다.

내장하려면 참조되고 있는 어셈블리어 Excel, word, Core등의 어셈블리어를 선택하시고 프로퍼티에 Embed Interop Type 옵션을 True로 변경 해야합니다. 

[그림 3] Embed Interop Type 설정


이렇게 True로 설정하게 되면 컴파일 타임에서 등록해야하는 레지스터리를 사전에 코드에 내장을 하여 불필요한 타입 패턴을 일치 하실 필요가 없으며 런타임 시점에서 dynamic mapping을 하게 됩니다.

[소스 참고]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. 방법: Visual C# 2010 기능을 사용하여 Office Interop 개체에 액세스(C# 프로그래밍 가이드)
    :
http://msdn.microsoft.com/ko-kr/library/dd264733.aspx


포스팅을 마치며...

짧게 리뷰를 해보았는데요. 어떠셨는지 모르겟어요 ^^;
제법 강력해졌다라고 표현을 해드리고 싶습니다. 또한 NO-PIA 옵션으로 하위 버전에서 해당 구문이 실행이 가능하다는 사실 잊지마시구요 이제 NO-PIA 옵션을 활용 해보세요 : )

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

다음 포스팅은 공변성과 반공변성(Co-Variance and Contra-Variance)에 대해서 살펴보도록 하겠습니다.
감사합니다.

정은성 드림


PS. 이번주는 태풍이 온다네요. 우산 꼭 챙기세요 ^ㅁ^
Posted by LenAWeb

댓글을 달아 주세요

  1. 매우 지원, 아주 좋아.

    2013.04.05 16:27 [ ADDR : EDIT/ DEL : REPLY ]
  2. 헤여졌다한들 슬퍼하지마. 이후에 만나게될 더좋은 사람을 위해 항상 웃는얼굴 잃지 말자.

    2013.04.07 00:43 [ ADDR : EDIT/ DEL : REPLY ]
  3. 당신이 슬퍼 느낄 때 고통, 무슨 내용을 보려면하는 것이 가장 좋습니다. 학습은 천하무적 할 것입니다.

    2013.04.08 00:44 [ ADDR : EDIT/ DEL : REPLY ]
  4. 모든 사람은 죽는다. 하지만 모든 사람이 진정한 삶을 사는 건 아니다.

    2013.04.08 08:21 [ ADDR : EDIT/ DEL : REPLY ]
  5. 당신이 슬퍼 느낄 때 고통, 무슨 내용을 보려면하는 것이 가장 좋습니다. 학습은 천하무적 할 것입니다.

    2013.04.09 21:14 [ ADDR : EDIT/ DEL : REPLY ]
  6. http://www,Topics related articles:


    http://webstoryboy.com/256 复件 (10) 韩

    .xn--6ck2bwcu74pofcq24aotk.com/
    http://www,Topics related articles:


    http://important.tistory.com/420 复件 (10) 韩

    .lisseurghdle,Topics related articles:


    http://www.hanbajo.com/?page=3 复件 (15) 韩

    .com/

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

    2013.04.23 21:02 [ ADDR : EDIT/ DEL : REPLY ]
  8. 슬퍼서 우는거 아니야..바람이 불어서 그래..눈이 셔서..

    2013.07.17 11:39 [ 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

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 ]

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

03| Dynamic 유형 객체 #1 : DLR


구독자 여러분 안녕하세요 생각보다 포스팅이 많이 늦어졌죠?
최근에 처리할일이 생각보다 많아서 포스팅을 쓸 여력이 되지 않았습니다.
앞으로 열심히 쓰고자 하니깐 용서해주세요 ~ 흑흑...

오늘은 지난 시간에 이어서 C#의 새로운 기능에 대해 소개를 할텐데요.
그 첫번째 시간으로 동적 타입에 대해 소개를 하고자 합니다.

지난 Microsoft는 MIX07과 PDC2008 등을 통해 .NET에서 새로운 수준의 지원을 발표를 하였습니다.
바로 .NET 프레임워크에서 서로 다른 프로그래밍 언어를 광범위한 지원을 하도록 설계가 되어졌는데요.

그배경에 공용언어 런타임(Common Language Runtime)의 Sandbox 보안 모델이 발전되면서 GC(Garbage Collection), JIT(just-in-time)를 더불어 공유 서비스를 제공하면서 각 다른 언어의 라이브러리를 손쉽게 가져다 쓸수 있었기에 정적인 언어와 동적인 언어를 구별하여 사용할수 있었지 않았나 생각이 듭니다.

* Sandbox(샌드 박스)
보호된 영역내에서 프로그램을 동작시키는 것으로 외부 요인에 의해 악영향이 미치는 것을 방지하는 보안 모델, ' 아이를 모래밭(샌드 박스)의 밖에서 놀지 않는다 ' 라고 하는 말이 어원이라고 알려져 있다. 이모델에서는 외부로부터 받은 프로그램을 보호된 영역, 즉, '상자'안에 가두고 나서 동작시킨다. '상자'는 다른 파일이나 프로세스로부터 격리되어 내부에서 외부를 조작하는 것은 금지 되어 있다.

어느듯 .NET Framework 4 버전의 런칭이 되면서 공용 언어 런타임(Common Language Runtime)이 2.0에서 4.0으로 업그레이드가 되었는데요. 그동안 Silverlight 1.1에서 지원을 했던 DLR(Dynamic Language Runtime)이 다시 주목을 받으면서 C# 4.0은 완전한 프로그래밍으로 초점을 맞추어 나가고 있습니다.

먼저 간단히 DLR(Dynamic Language Runtime)에 대해서 살펴 보아야 할것 같습니다.
Dynamic Language Runtime은 CLR 상단부에 위치하고 있으며 주요 구성은 다음과 같습니다.
[그림 1 : Dynamic Language Runtime Architecture ]

DLR은 3가지 주요 구성요소를 가지고 있는데요. 어떻게 동적 언어를 실행하기 위해 협력을 하는지 설명을 해드리겠습니다. 

- Expression Trees
: 트리를 사용하여 구조적 표현의 의미를 노드로 나타냅니다. 다른 언어의 모델링을 지원하기 위해 확장된 LINQ 표현식 트리를 포함하여 동적인 변수 연산이나 변수, 이름 바인딩과 제어흐름 등이 추가 되어 DLR의 중추 역활을 담당합니다.

  표현 트리식에 대해서 궁금하시면 아래 URL을 참고 해주세요 
  표현 트리식 : 
http://msdn.microsoft.com/ko-kr/library/bb397951.aspx

- Dynamic Dispatch 
: DLR에서는 동적 개체 및 작업을 나타내는 인련의 클래스와 인터페이스를 제공합니다. 언어를 구현하거나 동적 라이브러리를 작성할 때 제공되는 클래스와 인터페이스를 사용할 수 있습니다. 해당하는 클래스와 인터페이스로는 IDynamicMetaObjectProvider, DynamicMetaObject, DynamicObject 및 ExpandoObject가 있습니다.

- Call Site Caching
:  런타임 환경에서 실행되어질 동적 개체 대해서 코드에 대한 정보를 은닉해둠으로써 이후 동일 액션의 호출시 수행속도를 향상하는 역활을 합니다. 예를 들어 a + b와 같은 연산이 있을때 a, b의 특징과 작업 관련된 정보를 캐싱해두었다가. 만약 어떠한 작업을 수행해야할때 이전에 그와 같은 작업을 수행한적이 있다면 DLR에서 캐싱된 내용을 디스패치 하여 속도를 향상시킵니다.

위와 같은 구성원이 서로 협력을 통해  동적 프로그래밍이 각 바인더별로 실행이 가능하도록 지원을 하고 있습니다.
DLR에 대해서는 여기까지 살펴보도록 하고 Dynamic lookup에 대해서 살펴보도록 하겠습니다.
혹 자세한 설명이 필요 하시다면 First Look C# 4.0 whiepaper 를 참고하시거나 별도 포스팅을 기획할 예정입니다

참고 문헌

1. 식 트리(C# 및 Visual Basic)

    : http://msdn.microsoft.com/ko-kr/library/bb397951.aspx

2. PDC2008 : The Future of C# - Anders Hejlsberg
    : http://channel9.msdn.com/pdc2008/TL16/

3. A Dynamic Language Runtime (DLR) - Jim Hugunin's Thinking Dynamic
    :
http://blogs.msdn.com/b/hugunin/archive/2007/04/30/a-dynamic-language-runtime-dlr.aspx
4. DLR Trees (Part 1) - Jim Hugunin's Thinking Dynamic
    : http://blogs.msdn.com/b/hugunin/archive/2007/05/15/dlr-trees-part-1.aspx



포스팅을 마치며...

갑자기 일이 많아져서 포스팅이 늦어졌는데요. dynamic lookup을 살펴보기전에 DLR 존재의 여부에 대해 전달 할 필요가 있는것같아 간소화하게 작성하게 되었는데 왠지 모를 어색하고 주절주절 한 포스팅 이 되어버렸네요 T.T

다음 회차에서는 dynamic lookup의 특징과 C#의 새로운 프로그래밍 스타일인 duck typing 에 대해 살펴볼 예정입니다.
무더위 준비 잘하시고 좋은 하루 되세요 : )
감사합니다.

정은성 드림
Posted by LenAWeb

댓글을 달아 주세요

  1. 그거아니,Topics related articles:


    http://easymusic.co.kr/94 韩

    ,세상에너밖에없어서,Topics related articles:


    http://unendinglove.co.kr/1493 复件 (2) 韩

    ,널사랑하는게아니라,널사랑하니까,Topics related articles:


    http://www.chunhwa244.net/category/들마는달린다 复件 (15) 韩

    ,세상에너밖에없다는거

    2013.04.11 01:36 [ ADDR : EDIT/ DEL : REPLY ]
  2. http://www,Topics related articles:


    http://no-surrender.tistory.com/369 复件 (20) 韩

    .christianlouboutinve,Topics related articles:


    http://hancd.com/archive/201209 复件 (17) 韩

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


    http://www.cafeleeu.com/archive/20120409 复件 (14) 韩

    .com/

    2013.04.22 01:01 [ ADDR : EDIT/ DEL : REPLY ]
  3. 슬픔을 나누면 반으로 되지만, 기쁨을 나누면 배가된다.

    2013.04.23 20:56 [ ADDR : EDIT/ DEL : REPLY ]
  4. 다른 남자 부르면서 울거면 나한테 이쁘지나 말던지

    2013.04.28 06:37 [ ADDR : EDIT/ DEL : REPLY ]
  5. 창밖을 봐 바람에 나뭇가지가 살며시 흔들리면 네가 사랑하는 사람이 널 사랑하고 있는거야.

    2013.07.18 06:53 [ 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

02| C# 4.0 개요

이번 포스팅은 .NET Framework 4의 " C# 새로운 기능 소개와 출현배경" 에 대해 아티클로 다뤄보도록 하겠습니다.

그동안 2.0 버전에서 머물렀던 CLR(Common Language Runtime)이 .NET Framework 함께 4.0 버전으로 업그레이드가 되었습니다. CLR의 가장 큰 변화로는 DLR(Dynamic Language Runtime)을 통해 언어의 유연성이 느슨하게 되면서 DOM, IronRuby, IronPython 등  동적인 언어를 사용 할수 있도록 설계 되어졌습니다.



지금까지 Visaul C#언어는 정적 언어 였습니다. 정적 언어라고 하면 명확하게 타입 선언과 사용이 매칭이 되어야합니다. 만약 숫자를 사용하고 싶다면 int형 타입으로 선언을 해야하며 그리고 문자열 사용하고 싶다면 string형 타입으로 선언과 타입을 넘겨줘야합니다. 그런데 왜 이제서야 동적 언어를 지원을 하게 되었을까요? C# 디자인팀에서 4.0을 설계 할때 2가지 컨셉중심으로 준비 하였다고 합니다.

[그림1] C# 4.0 컨셉


첫번째 컨셉은 Dynamic Programming 인데요
Dynamic Programming은 4.0에서 등장 했던 것은 아닙니다. invokeMember와 같이 Reflection을 이용하여 동적으로 사용이 가능했습니다. 하지만 메모리 소모량도 크고 불안정하기 까지 하였습니다. 그래서 C# 4.0에서는 DLR(COM Interop 포함)에 대한 높은 호환성과 Iron 시리즈의 스크립팅 언어를 비롯해 늦은 바인딩 언어를 지원하고자 dynamic 키워드를 도입하게 되었고 유연성을 허용 하게 되었습니다.

두번째 컨셉으로는 co-evolution with VB 입니다.

지난 10년간 .NET Framework가 발전을 하면서 VB, C#, C++, IronRuby, IronPython, JScript , J# 등 많은 언어들을 지원하며 Managed 하게 진화해 왔습니다. 그중 마치 형제인듯 공존하며 성장을 해왔던 언어가 있는데요.

바로 VB와 C#언어 입니다. 마침 MS OFFICE 프로그램의 오토메이션 사례등 유사한점을 확인 할 수 있었습니다. 예를들어 어떠한 데이터를 셀에 삽입한다고 가정할 때 C#에서는 Value2라는 속성을 사용하였고 반면 VB에서는 Value라는 속성을 사용하였습니다.  이들의 특징은 동일한 내용의 타입 이였고 동일한 시나리오의 수행이였습니다. 그럼 구현의 퍼포먼스에서는 어땠을까요? VB에서는 사용이 쉬운 반면 C#에서는 전혀 알지도 못한 타입 함께 사용하게 되었습니다. 자연스럽게 코드가 복잡해지고 어려울수 밖에 없었죠. 이러한 기존 VB의 특징을 바탕으로 어떻게 하면 효율적으로 사용할것인지 또한 어떻게 COM객체와 상호연동을 할것인지? 등 함께 성장하자라는 취지로 C# 4.0이 탄생하게 되었습니다.

다음은 두 컨셉의 기반으로 탄생한 C# 4.0의 새롭게 추가된 구성원이 무엇인지 간단히 살펴보도록 하겠습니다.

[그림2] C# 4.0의 새로운 기능들


* C# 4.0의 새로운 기능들

- Dynamically Typed Objects(Dynamic Lookup)
- Optional and Named Parmeters
- Com-specific interop features
- Generic Co-Variance and Contra-Variance

명칭만으로도 궁금증을 돋아 주는데요. 아쉽게도 이번 포스팅에서는 헤드라인 만 살펴봐야할것 같습니다.
다음 포스팅부터 새롭게 추가된 기능에 대해 순차적으로 만나뵐 예정이구요.

궁금하셔도 조금만 기다려주세요 : )
그래도 궁금하시다면 아래 참고 문헌을 참조하시면 됩니다.

여러분 다음 포스팅에 만나요 =ㅁ=//


참고 문헌

1. New Features in C# 4.0 - Mads Torgersen, C# Language PM(April 2010)

    : http://msdn.microsoft.com/en-us/vcsharp/ff628440(en-us).aspx

2. What's New in Visual C# 2010
    : http://msdn.microsoft.com/kr-ko/library/bb383815.aspx

3. PDC2008 : The Future of C# - Anders Hejlsberg
    : http://channel9.msdn.com/pdc2008/TL16/



포스팅을 마치며...

어떤 느낌을 받으셨나요? 아직 무엇인지는 알 수 없지만 의미적으로 많은 지원을 제공하고자 Microsoft에서 야심차게 준비하는 모습을 볼 수 있었습니다. 다음 포스팅 에서는 새로운 기능의 특징들을 순차적으로 살펴 보도록 하겠습니다.
앞으로도 관심 부탁드리며 무더위 준비 잘하시길 바라면서 글 이만 줄이도록 하겠습니다.
감사합니다.

정은성 드림

PS. DLR에 대한 내용은 별도로 포스팅 예정입니다.  조금만 기다려주세요 ^^

Posted by LenAWeb

댓글을 달아 주세요

  1. C#의 Dynamic Lookup에서는 call-site라 불리는 캐슁 공간을 이용해서 각각 바인딩 된 인스턴스를 캐슁합니다. 또한 IDynamicObjectProvider 객체를 통해 Lookup 과정을 거게 되죠. 이러한 메카니즘 덕분에 동적타입일지라도 아주 빠르게 동작할수 있습니다.

    2010.07.08 11:39 [ ADDR : EDIT/ DEL : REPLY ]
  2. 참된 행복은 자기만족에서 오는 것이 아니라,가치있는 목적을 충실하게 추구할 때 오는 것이다.

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

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

    2013.04.23 17:45 [ ADDR : EDIT/ DEL : REPLY ]
  5. 눈을 감아봐 입가에 미소가 떠오르면 네가 사랑하는 그 사람이 널 사랑하고 있는거야.

    2013.04.28 05:29 [ ADDR : EDIT/ DEL : REPLY ]
  6. 사람들은 죽을걸 알면서도 살잖아 .사랑은 원래 유치한거에요

    2013.07.12 09:28 [ ADDR : EDIT/ DEL : REPLY ]