C#

object vs dynamic vs var – 언제 뭘 써야 헷갈리지 않을까?

Juan_ 2025. 6. 6. 09:55
728x90

object vs dynamic vs var – 언제 뭘 써야 헷갈리지 않을까?

C# 코드 짜다 보면 아래 셋 중에 뭐 써야 할지 헷갈릴 때가 있다.


object something = ...;
dynamic something = ...;
var something = ...;

전부 '뭔가를 담을 수 있다'는 느낌인데…

똑같은 거 같으면서도 다르고, 다르다면서도 비슷하다.

"object는 옛날부터 있던 거고, dynamic은 늦게 생긴 거고, var은 타입 추론 아닌가?"

이 정도만 알고 있으면 실무에선 딱 사고 난다.

이번 챕터에선 이 셋을 진짜 제대로 구분해보자.
헷갈리는 개념, 예외 상황, 실무 기준 사용법까지 싹 정리해줄게.


문제 상황: 자동완성도 안 뜨고, 컴파일 에러도 없고?


dynamic x = "Hello";
Console.WriteLine(x.Length); // 가능

object y = "Hello";
Console.WriteLine(y.Length); // ❌ 컴파일 에러

어라? 둘 다 문자열인데 왜 object는 안 되고 dynamic은 되지?

핵심은 타입 해석 시점의 차이다.

  • object: 컴파일 타임에 타입이 결정됨 (그래서 .Length 못 씀)
  • dynamic: 런타임에 타입이 결정됨 (그래서 일단은 뭐든 호출 가능)
  • var: 컴파일 타임에 명확한 타입으로 결정됨 (단, 선언할 때만!)

object – C#의 최상위 조상

모든 타입은 결국 object에서 파생된다.
그래서 어떤 타입이든 object 변수에 담을 수 있다.


object value = 123;         // int
object text = "hello";      // string
object now = DateTime.Now;  // DateTime

하지만 문제가 있다.
object로는 구체적인 멤버를 쓸 수 없다.
왜냐면 object 타입에 그런 게 없으니까.


object text = "hello";
Console.WriteLine(text.Length); // ❌ 컴파일 에러
Console.WriteLine(((string)text).Length); // ✅ 형변환 필요

object는 유연하지만, 구체적인 작업을 하려면 형변환이 필요하다.


dynamic – 일단 뭐든 해봐! (책임은 런타임에)

dynamic은 런타임까지 타입 검사를 미룬다.
컴파일러가 “나 몰라~ 일단 통과시킬게”라는 스타일.


dynamic x = "hello";
Console.WriteLine(x.Length); // ✅

dynamic y = 123;
Console.WriteLine(y.Length); // ❌ 컴파일은 되지만, 실행 중 예외

런타임에 잘못된 멤버를 호출하면 바로 예외가 터진다.

실무에서는? 외부 데이터 (예: JSON, COM, Reflection 등)를 다룰 때 잠깐 쓴다.


var – 타입 추론의 왕자님

var는 선언 시점에 타입을 추론해서 자동으로 결정해주는 키워드다.
한 번 결정된 타입은 고정된다.


var x = "hello";    // string
var y = 123;        // int
var z = new List<string>(); // List

var는 타입을 감추는 게 아니라, 타입을 자동으로 결정해주는 것이다.


var a = null;   // ❌ 에러: 타입 추론 불가
var b;          // ❌ 에러: 반드시 초기화 필요

var x = "hello";
Console.WriteLine(x.Length); // ✅ 잘 동작

실무 예시: JSON, object, var, dynamic


string json = "{ \"Name\": \"철수\" }";

var obj = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
Console.WriteLine(obj["Name"]); // object니까 형변환 필요

dynamic dyn = JsonSerializer.Deserialize<dynamic>(json);
Console.WriteLine(dyn.Name); // dynamic이니까 바로 접근 가능

object는 안전하지만 귀찮고,
dynamic은 편하지만 위험하다.
var는 명확한 타입을 추론할 수 있을 때 쓰면 깔끔하다.


언제 어떤 걸 써야 할까?

구분 object dynamic var
타입 해석 시점 컴파일 타임 런타임 컴파일 타임 (추론)
멤버 접근 형변환 필요 직접 접근 가능 타입에 따라 가능
타입 안정성 높음 낮음 높음
예외 가능성 컴파일 에러 런타임 예외 컴파일 에러
추천 상황 박싱된 값, 범용 컨테이너 외부 데이터(JSON 등) 명확한 타입을 추론할 수 있을 때

마무리하며

셋 다 “뭔가 유연하게 값을 담는” 역할처럼 보이지만, 실제로는 전혀 다른 철학과 목적을 갖고 있다.

  • "최대한 범용으로 받고 싶고, 타입은 나중에 처리한다" → object
  • "외부 데이터니까 일단 접근하고, 예외는 감수하겠다" → dynamic
  • "타입은 명확한데 코드 깔끔하게 쓰고 싶다" → var

실무에선 object와 dynamic을 무분별하게 남용하는 건 피하고, 가능하면 명확한 타입을 기반으로 코딩하는 습관을 들이자.

그게 유지보수와 안정성의 핵심이다.

728x90