Back End/🌈 ASP.NET
string VS string? VS string.Empty
James Wetzel
2025. 6. 15. 14:46
public class MyModel
{
// 컴파일러에게 null이 될 수 있음을 알림.
// 하지만 런타임 시에는 이 속성이 필수임을 [Required]로 강제.
[Required]
public string? RequiredField { get; set; }
// 컴파일러에게 null이 될 수 있음을 알림.
// 런타임 시에도 null을 허용함 (필수 아님).
public string? OptionalField { get; set; }
// 컴파일러에게 null이 될 수 없음을 알림. (경고 발생 가능성 있음)
// 런타임 시에는 필수임을 강제.
[Required]
public string AnotherRequiredField { get; set; } = string.Empty; // 보통 이렇게 초기화하여 경고 방지
}
string? (컴파일러 레벨)
- 목적: 컴파일러가 잠재적인 null 참조 오류를 감지하도록 돕는 기능입니다. string?이라고 선언하면, 컴파일러는 이 변수가 null일 수 있음을 인지하고, null이 될 가능성이 있는 부분에서 해당 변수를 사용하기 전에 null 체크를 하도록 경고하거나 강제할 수 있습니다 (Nullable 경고 활성화 시).
- 컴파일러 경고: string? Username은 Username이 null일 가능성이 있으니, 혹시 null일 때 발생하는 NullReferenceException을 조심하라고 알려주는 것입니다.
[Required] (런타임 유효성 검사 레벨)
- 목적: 해당 속성이 필수 값이어야 한다는 런타임 유효성 검사 규칙을 정의합니다. 클라이언트로부터 전송된 데이터가 서버의 모델 바인딩 과정을 거칠 때, 이 규칙에 따라 유효성을 검사합니다.
- [Required]가 붙은 속성에는 null 또는 기본값(예: string의 경우 null 또는 string.Empty에 가까운 값, int의 경우 0 등)이 올 수 없다는 의미입니다.
왜 함께 사용될까요?
이 두 가지를 함께 사용하는 것은 컴파일러의 안정성 보장과 런타임 시 데이터 유효성 검사라는 두 가지 목표를 모두 달성하기 위함입니다.
- 컴파일러 경고 방지: public string Username { get; set; } (Nullable이 아닌 참조 형식)으로 선언하고 [Required]를 붙이면, 만약 어떤 코드에서 Username에 null이 할당될 가능성이 있다면 컴파일러는 Nullable 경고를 띄울 수 있습니다. string?을 사용하면 "이 속성은 null이 될 수도 있지만, [Required]가 있으니 유효성 검사는 할 거야"라고 명시하여 컴파일러의 간섭을 줄일 수 있습니다.
- 명확한 의도 표현: string?을 통해 개발자는 이 속성이 때로는 null 값을 가질 수 있음을 코드 상에서 명시합니다. 그리고 [Required]를 통해 "하지만 이 API 엔드포인트에 대한 입력으로는 절대 null이 와서는 안 된다"는 비즈니스 규칙을 명확히 전달합니다.
- 데이터 유효성 검사 강제: 가장 중요한 부분입니다. 클라이언트가 username 필드를 비워두거나 null로 전송하면, [Required] 어노테이션 덕분에 ASP.NET Core의 모델 바인딩 및 유효성 검사 시스템이 이를 감지하고 ModelState.IsValid가 false가 되어 BadRequest 응답을 반환하게 됩니다. string? 선언만으로는 이런 런타임 유효성 검사를 제공하지 않습니다.
728x90
반응형