동적 형식(Dynamic Type)

  • 8 minutes to read

C#은 태생적으로 정적(static) 형식의 언어입니다. 하지만 c# 4.0부터는 파이썬과 자바스크립트와 같이 동적(dynamic) 형식도 지원합니다. 이번 강의에서는 동적 형식을 간단히 알아보겠습니다.

> // dynamic: 런타임에 데이터 형식이 결정되는 모든 형식을 담을 수 있는 특수한 유형의 형식

dynamic 키워드

C#에서는 dynamic 키워드를 사용하는 동적 형식을 제공합니다. 간단히 말해 컴파일 시점에서는 형식이 정해지지 않고 런타임 시점에 형식이 정해지는 특수한 유형의 형식입니다.

  • 컴파일 타임에 형식이 지정되는 프로그램은 편합니다. 바로 int, string 형으로 변수를 선언한 후 해당 값을 사용하면 됩니다.
  • 런타임에 형식이 지정되는 프로그램이 필요할 수 있습니다. 이런 경우에는 dynamic 키워드를 사용하여 변수를 선언할 수 있습니다.
  • dynamic 키워드는 데이터 형식 자리에 오지만 dynamic은 데이터 형식은 아닙니다. 즉, dynamic 키워드는 특정 데이터 형식을 지칭하지 않습니다.
  • var 키워드와 비슷하나 컴파일 시에 데이터 형식이 결정되는 var와 달리 dynamic 키워드는 런타임 시에 데이터 형식이 결정됩니다.
  • 모든 데이터 형식을 선언하는 자리에는 dynamic 키워드를 사용할 수 있습니다.
  • 동적 형식은 다른 동적 언어와의 통신에 유용하게 사용됩니다.

dynamic 변수로 런타임 시에 데이터 형식 결정

동적 형식을 사용할 수 있도록 dynamic 키워드로 변수를 선언하고 사용하는 예제를 살펴보겠습니다.

코드: Dynamic.cs

> dynamic x;
> 
> x = 1234; // [1] int
> Console.WriteLine(x); // 1234
1234
> Console.WriteLine(x.GetType()); // System.Int32
System.Int32
> 
> x = "Dynamic Type!"; // [2] string
> Console.WriteLine(x); // "Dynamic Type!"
Dynamic Type!
> Console.WriteLine(x.GetType()); // System.String
System.String

동적 형식을 나타내는 dynamic 키워드로 변수를 선언하면 컴파일 시점에서는 형식이 결정되지 않고 실행 시점에서의 데이터에 의해서 자동으로 데이터가 결정됩니다. [1]번 코드에서처럼 1234와 같이 정수 형식의 데이터가 대입되면 실행 시점에서는 정수 형식으로 처리되고 [2]번 코드에서처럼 문자열 데이터가 대입되면 이를 사용하는 실행 시점에서는 문자열로 데이터가 처리됩니다. 컴파일 시점에는 데이터 형식이 결정되지 않기에 박용준 강사가 생각하는 dynamic 키워드의 유일한 단점의 Visual Studio의 인텔리센스의 도움을 받을 수 없다는 것입니다.

런타임에 데이터 형식이 결정되는 dynamic 변수

프로그램 코드 상에서 dynamic은 컴파일 타임에는 그 자체로 존재하다가 런타임에서 형식 추론에 의해서 데이터 형식이 결정되는 형태이기에 없는 속성을 나중에 원하는만큼 추가해서 사용 하는 등의 기능을 구현할 때 편리하게 사용할 수 있습니다.

코드: DynamicallyTypedObjects.cs

> //[?] `dynamic` 키워드로 선언된 변수는 런타임 시점에 데이터 형식이 결정된다. 
> dynamic x = 1; // 컴파일 시 dynamic, 런타임 시 System.Int32
> dynamic y = "Hello"; // 컴파일 시점에는 dynamic, 런타임 시점에는 System.String 
> 
> Console.WriteLine($"x: {x}, {x.GetType()}"); 
x: 1, System.Int32
> Console.WriteLine($"y: {y}, {y.GetType()}");
y: Hello, System.String

문자열 변수를 string, var, dynamic 키워드로 선언하기

동적 형식인 dynamic 키워드는 var 키워드와 전혀 다름을 알아야 합니다. 이번에는 기본 데이터 형식을 지정한 변수와 var 키워드를 사용한 암시적으로 형식화된 변수 그리고 danymic 키워드를 사용하는 동적 형식의 변수를 3가지 만들고 간단히 코드로 비교해보겠습니다.

코드: DynamicDemo.cs

> //[?] `dynamic` 키워드: 런타임에 데이터 형식이 결정되는 변수를 생성
> string ss = "안녕하세요."; //[1] 코드 작성시 문자열로 판단
> Console.WriteLine(ss.Length); // 인텔리센스의 도움 받음
6
> 
> var vs = "반갑습니다."; //[2] 컴파일시 문자열로 판단
> Console.WriteLine(vs.Length); // 인텔리센스의 도움 받음
6
> 
> dynamic ds = "또 만나요."; //[3] 런타임시 문자열로 판단
> Console.WriteLine(ds.Length); // 인텔리센스의 도움 못 받음
6
> 
> ds = 1234; // [4]런타임시 숫자형으로 판단
> Console.WriteLine(ds * 10); // 숫자형 연산이 가능: 12340
12340

[1]번과 [2]번과 같은 형태는 지금까지 우리가 사용해 온 강력한 형식의 변수를 선언하는 방식입니다. [3]번과 같이 dynamic 키워드를 사용하면 동적으로 문자열 또는 정수 형식과 같이 런타임에 사용할 변수를 동적으로 만들 수 있습니다.

동적 바인딩

런타임 시에 데이터 형식이 결정되는 것을 동적 바인딩(Dynamic Binding)이라고도 합니다.

코드: DynamicBinding.cs

> //[?] 동적 바인딩
> dynamic now = DateTime.Now; 
> int hour = now.Hour;
> Console.WriteLine(hour);
3
> now.NoProperty
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.DateTime'에 'NoProperty'에 대한 정의가 없습니다.
  + System.Dynamic.UpdateDelegates.UpdateAndExecute1<T0, TRet>(System.Runtime.CompilerServices.CallSite, T0)

DateTime 구조체 형식에는 NoProperty 속성이 없기에 컴파일 시점에는 에러가 나지 않지만, 런타임 시점에서는 에러가 발생합니다.

확장 메서드와 dynamic

확장 메서드는 정적 형식에서는 제대로 호출이되지만, 동적 형식에서는 호출되지 않습니다.

코드: DynamicExtensionMethod.cs

using System;

static class DynamicExtensionMethod
{
    // 확장 메서드 
    static string PreDotNet(this string str) => $"....{str}";

    static void Main()
    {
        string s1 = "DotNet";
        Console.WriteLine(s1.PreDotNet()); //[1] 실행됨

        dynamic d1 = "Korea";
        Console.WriteLine(d1.PreDotNet()); //[2] 에러 발생
    }
}
....DotNet

처리되지 않은 예외: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'string'에 'PreDotNet'에 대한 정의가 없습니다.
   위치: CallSite.Target(Closure , CallSite , Object )
   위치: System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   위치: DynamicExtensionMethod.Main() 파일 C:\DotNet\DotNet\DotNet\DotNet\52_Dynamic\DynamicExtensionMethod\DynamicExtensionMethod.cs:줄 14

장 요약

C#이 dynamic 키워드를 제공하여 동적 형식을 만들어 낼 수 있습니다. 하지만, C#으로만 개발할 때에는 강력한 형식으로 개발을 하는게 좋습니다. 만약, 동적인 언어와의 호환 프로그램을 작성한다던가 웹 개발시 MVC 패턴처럼 컨트롤러에서 뷰로 서로 다른 계층으로 데이터를 전송할 때 등의 경유에는 동적 형식을 사용하면 코드 작성의 편의성은 있습니다. 특별히 오랜기간 C#을 사용해 왔지만, 학습을 시작하는 일반적인 경우에는 dynamic 형식을 많이 사용하진 않기에 간단히 예제 몇 개만 살펴보는 식으로 마무리 하였습니다.

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com