dynamic 한 줄 정의
보통 int, string 같은 정적 타입들은:
그런데 dynamic은 이렇게 행동한다:
“지금 컴파일할 땐 타입 검사하지 말고,
실행할 때 실제 타입을 보고 알아서 동작해봐.”
그래서:
이런 것들이 전부 런타임에 결정된다.
dynamic x = 10;
x = "Hello"; // OK, 타입 바뀌어도 컴파일 에러 없음
x = DateTime.Now; // OK
Console.WriteLine(x.NonExistMethod()); // 컴파일은 통과하지만...
이 코드를 보면:
x.NonExistMethod()를 호출하려고 할 때,
실제 x 타입에 그런 메서드가 없으면RuntimeBinderException 예외가 터진다
반대로, 같은 걸 object로 쓰면:
object x = 10;
x.NonExistMethod(); // ❌ 컴파일 에러 (object에는 그런 메서드 없음)
object일 때는 컴파일러가 타입을 알고 있으니까:
“야,object에는NonExistMethod같은 멤버 없어.” → 컴파일 단계에서 바로 막아버린다.
정리하면:
object → 컴파일 시점에 타입이 object라서, object 범위 안에서만 사용 가능dynamic → 컴파일러가 타입 체크를 포기하고, 실행 시점에 실제 타입 기준으로 멤버를 찾고 호출을 시도dynamic vs var – 제일 많이 헷갈리는 포인트거의 100% 한 번씩 헷갈리는 부분이라, 확실히 정리해 두는 게 좋다.
varvar s = "Hello"; // s는 컴파일 타임에 string으로 확정
s = 123; // ❌ 컴파일 에러 (int 대입 불가)
var는 그냥 “형식 추론”일 뿐이다.s를 보고 “아, 이건 string이구나”라고 딱 정해버린다.string 변수처럼 완전히 작동한다.dynamicdynamic s = "Hello"; // s의 런타임 타입은 string, 컴파일러는 타입 검사 안 함
s = 123; // OK, 이제 런타임 타입은 int로 바뀜
dynamic은 타입이 런타임에 바뀔 수 있다.| 키워드 | 의미 | 타입 결정 시점 | 타입 체크 |
|---|---|---|---|
var |
형식 추론 (컴파일 시) | 컴파일 타임 | 컴파일 타임에 엄격하게 검사 |
dynamic |
런타임 바인딩 (동적 타입) | 런타임 | 런타임에 검사 |
dynamic은 어디에 쓰는 게 좋을까?
대부분의 C# 코드는 정적 타입으로 깔끔하게 짜는 게 좋다.
그래도 dynamic이 유용한 상황이 분명 있다.
기존 스타일:
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application app = new Excel.Application();
Excel.Workbook wb = app.Workbooks.Open("test.xlsx");
Excel.Worksheet ws = (Excel.Worksheet)wb.Sheets[1];
인터페이스/캐스팅이 많아서 코드가 좀 번거롭다.
dynamic을 쓰면:
dynamic app = new Excel.Application();
dynamic wb = app.Workbooks.Open("test.xlsx");
dynamic ws = wb.Sheets[1];
ws.Cells[1, 1].Value = "Hello";
dynamic에 넣고 쓰면, 캐스팅/구체 타입을 덜 신경 써도 된다.예를 들어 IronPython, ClearScript 같은 스크립트 엔진과 연동할 때:
dynamic으로 받아서 “그냥 메서드 있는 것처럼” 호출할 수 있다.dynamic pyObj = GetPythonObject(); // 예시
pyObj.Run(); // 런타임에 Run이 있는지 확인 후 호출
ExpandoObject를 가볍게 다룰 때예를 들어 Newtonsoft.Json을 사용할 때:
dynamic obj = JsonConvert.DeserializeObject(json);
Console.WriteLine(obj.name);
Console.WriteLine(obj.address.city);
Person 같은 타입으로 매핑하는 게 더 타입 안정성이 좋다.dynamic 동작static void PrintLength(dynamic x)
{
Console.WriteLine(x.Length);
}
PrintLength("Hello"); // string.Length → 5
PrintLength(new int[] {1,2,3}); // 배열.Length → 3
PrintLength(123); // int에는 Length 없음 → 런타임 예외
컴파일러 입장:
dynamic이면 일단 Length가 있다고 믿자…” → 컴파일 OKLength를 찾는다.dynamic의 단점 / 주의할 점dynamic x = "Hello";
int n = x; // 컴파일 OK, 실행 시 예외 (string → int 변환 불가)
var나 일반 정적 타입이라면 컴파일 단계에서 잡아줄 수 있는 오류도,dynamic은 실행해 봐야만 알 수 있다.대부분의 일반적인 C# 개발에서는:
dynamic은 진짜 필요한 구석(interop, 스크립팅, 테스트용)에서