Quick Reference
nameof는 source identifier 이름을 string으로 만들고, typeof는 선언한 type의 Type metadata를, GetType()은 object의 runtime type을 돌려줍니다. sizeof 계열은 목적이 다른 low-level size query이므로 interop layout이나 allocation cost와 같은 뜻으로 섞지 않습니다.
ArgumentNullException.ThrowIfNull(name, nameof(name));
Type declared = typeof(IEnumerable<string>);
object value = "Mina";
Type runtime = value.GetType();
int intBytes = sizeof(int); // 4nameof(user.Name)은"Name"이지"user.Name"이 아닙니다.typeof(Base)는 source에 적은 type,value.GetType()은 실제 runtime type입니다.- safe code의
sizeof는 built-in unmanaged type과 enum에서 바로 쓸 수 있습니다. - custom type size와 native interop layout은
Unsafe.SizeOf<T>·Marshal.SizeOf<T>의 서로 다른 contract를 확인합니다.
이름과 type metadata
public sealed class User
{
public string Name { get; init; } = "";
}
string propertyName = nameof(User.Name); // Name
Type openList = typeof(List<>);
Type closedList = typeof(List<int>);nameof는 compile-time string literal로 바뀌므로 refactoring에 강하고 allocation·reflection을 하지 않습니다. log message, exception parameter name, property-change notification처럼 source member 이름이 필요할 때 씁니다. user-facing label 또는 serialized field name처럼 versioned external text에는 별도 constant/schema 정책을 둡니다.
typeof(T)는 generic type definition과 closed generic type을 구분할 수 있습니다. GetType()은 null receiver에서 호출할 수 없고, inheritance가 있으면 선언 타입과 다를 수 있습니다.
Animal animal = new Dog();
bool exactDog = animal.GetType() == typeof(Dog);
bool assignableToAnimal = animal is Animal;정확한 runtime type만 원하면 GetType() == typeof(T), 파생 type까지 허용하면 pattern is T 또는 typeof(T).IsAssignableFrom(...)의 방향을 의도에 맞게 고릅니다.
Size API의 서로 다른 계약
| API | 의미 | 주요 조건 | 사용처 |
|---|---|---|---|
sizeof(T) | C#이 정의한 unmanaged value의 byte 수 | built-in/enum은 safe, 그 밖은 current stable에서 unsafe context 필요 | low-level language code |
Unsafe.SizeOf<T>() | runtime managed representation의 size query | low-level runtime API, interop layout 보장 아님 | measured runtime-oriented code |
Marshal.SizeOf<T>() | marshaler가 보는 unmanaged layout size | StructLayout, field marshalling, platform ABI 영향 | native interop boundary |
int primitive = sizeof(int);
int enumSize = sizeof(ConsoleColor);
// unsafe context가 필요할 수 있는 custom unmanaged type 예:
// unsafe { int bytes = sizeof(MyUnmanagedStruct); }sizeof 결과로 managed object 전체 allocation, object header, GC 비용을 판단할 수 없습니다. reference를 가진 struct, padding, pointer size, marshalling attribute는 API마다 서로 다른 결과를 만들 수 있습니다. 먼저 managed memory를 보려는지, native ABI를 맞추려는지 목적을 정합니다.
자주 틀리는 부분
Unsafe.SizeOf<T>()가 안전 code에서 호출된다고 sizeof(T)와 같은 compiler rule이나 native ABI 보장을 얻는 것은 아닙니다. 특히 P/Invoke buffer size는 Marshal.SizeOf<T>(), StructLayout, target platform을 함께 검증해야 합니다.
GetType()으로 exact type을 비교하면 proxy나 파생 type을 의도치 않게 제외할 수 있습니다. validation, serialization, polymorphism 중 무엇을 검사하는지에 따라 exact match와 assignability를 구분하세요.
참고 링크
4 sources