* 정의
dynamic 타입은 컴파일 시간에 타입 검사를 피하기 위해 사용되는 타입이다. 컴파일러는 dynamic 타입을 컴파일 시간에 체크하지 않는 대신 컴파일러는 런타임에 타입을 가져온다. 이러한 dynamic 타입은 dynamic 키워드를 사용해서 정의할 수 있다.
dynamic 타입을 통해서 덕 타이핑을 실현시킬 수 있고 이는 어떤 문제를 유연하게 해결할 수 있도록 도와준다. 예를 들어 인터페이스를 설계하여 특정 동작들을 정의하고 이를 사용할 때 그 과정에서 상속 관계를 잘 구성하기 위해서는 경험과 노력이 필요하다. 하지만 덕 타이핑은 상속 관계를 이용하지 않기 때문에 프로그램의 동작 부분만 신경쓰면 된다.
하지만 덕 타이핑으로 코드를 작성한다면 비주얼 스튜디오의 기능(리팩토링, 인텔리센스 등)을 사용할 수 없고, 컴파일 시간에 확인할 수 없기 때문에 오류를 조기에 발견하지 못하는 문제점이 있을 수 있을 것 같다.
* 동작 방식
- 컴파일 타임과 런타임에서 처리
dynamic 타입으로 객체를 할당했을 때 컴파일러는 객체에 대한 메소드나 프로퍼티의 정확한 이름을 확인하지 못한다. 해당 메소드나 프로퍼티가 존재하지 않더라도 컴파일 타임에는 판단하지 못하기 때문에 이상 없이 컴파일 되지만 런타임에 메소드와 프로퍼티가 호환되지 않으면 예외를 발생시킨다. 매개변수로 잘못넘기거나 잘못변환(암묵적 변환이다.)하는 경우도 마찬가지로 예외를 발생시킨다.

하지만 컴파일 타임에서 결정하지 않기 때문에 메소드의 매개변수를 dynamic 타입할 수 있고 이를 통해 런타임에 어떠한 타입도 받을 수 있다.
- 컴파일 타임에서의 타입과 런타임에서의 타입
컴파일러는 dynamic 타입을 object 타입으로 컴파일 하지만 런타임에 실제 타입이 확인된다. dynamic 타입은 런타임에 할당된 값(오른쪽에 있는 값)을 기반으로 타입을 변경된다.
var과 다르게 dynamic은 실제 타입을 컴파일 타임에 확인할 수 없다.

다음 코드는 런타임에 실제 타입을 확인하기 위해 GetType()을 호출한 코드이다.
dynamic dynamicInt = 100;
Console.WriteLine("Value: {0}, Type: {1}", dynamicInt, dynamicInt.GetType());
dynamic dynamicString = "hello";
Console.WriteLine("Value: {0}, Type: {1}", dynamicString, dynamicString.GetType());
Value: 100, Type: System.Int32
Value: hello, Type: System.String
- var vs dynamic
| var | dynamic |
| 정적으로 타입이 결정된다. | 동적으로 타입이 결정된다. |
| 컴파일 타입에 컴파일러에 의해 결정된다. | 런타임에 컴파일러에 의해 결정된다. |
| 컴파일러는 초기화된 값에 따라 타입을 결정하기 때문에 선언 시 초기화 되어야 한다. | 컴파일 타임에 타입을 알 수 없기 때문에 선언 시 초기화하지 않아도 된다. |
| 초기화되지 않으면 오류가 발생한다. | 초기화되지 않아도 오류가 발생하지 않는다. |
| 인텔리센스 지원 | 인텔리센스 미지원 |
| 초기화시 타입이 결정되고 변경되지 않기 때문에 다른 타입으로 대입 연산을 할 수 없다. | 초기화시 타입이 결정되지 않고 타입이 변할 수 있기 때문에 다른 타입의 값으로 대입 연산하는 것이 가능하다. |
| 함수의 지역변수로만 사용 가능하며 값을 반환하거나 프로퍼티에 사용 불가능하다. | 값을 반환하거나 프로퍼티에 사용할 수 있다. |
'C#' 카테고리의 다른 글
| [C#] Generic Collection 구현 해보기 (0) | 2022.07.01 |
|---|---|
| [C#] 인터페이스(interface) (0) | 2022.06.28 |
| [C#] abstract (0) | 2022.06.28 |
| [C#] abstract class vs interface (0) | 2022.06.28 |
| [C#] const, readonly (0) | 2022.06.28 |