C#의 객체 초기자(Object Initializers)

In C# 프로그래밍 by Choi Kyung-sik

객체를 생성한 후 그 객체의 접근할 수 있는 프로퍼티 또는 (OOP를 위반하여 드물겠지만) 필드의 값을 설정하는 것이 일반적일 것이다. 객체 초기자(object initializers, 개체 이니셜라이저)는 이러한 일반적인 프로그래밍 패턴을 간단하게 하기 위한 것이다.

using System;
 
class Student {
  public string Name { get; set; }
  public int Age { get; set; }
 
  public override string ToString() {
    return Name;
  }
}
 
class MainEntryPoint {
  static void Main() {
    Student student = new Student() { Name = "John", Age = 21 };
    Console.WriteLine(student.ToString().ToUpper());
 
    String s = new Student { Name = "Tom", Age = 23 }.ToString().ToUpper();
    Console.WriteLine(s);
  }
}

14, 17번째 줄에 있는 코드가 객체 초기자 문법을 사용한 것이다.

Student student = new Student() { Name = "John", Age = 21 };

14번째 줄에 있는 위 코드는 C# 언어 명세서(CSharp Language Specification)에 따르면 다음과 동일한 결과를 가진다.

Student __student = new Student();
__student.Name = "John";
__student.Age = 21;
Student student = __student;

임시적인 __student 변수는 일부만 초기화된 객체를 참조하는 것을 방지하기 위한 것이다. 3번째 줄까지 예외를 던지지 않아야 4번째 줄의 대입문을 실행한다.

17번째 줄에서 볼 수 있듯이 매개변수가 없는 생성자를 호출할 때 괄호는 생략할 수 있다. 따라서 14번째 줄은 다음으로 대치할 수 있다.

Student student = new Student { Name = "John", Age = 21 };

위 코드에서 명령문의 끝을 나타내는 세미콜론(;)을 사용하고 있다. 객체 초기자 문법을 사용하는 실제적인 이점은 수식문 안에서 초기화가 이루어져 함수의 조합성(composability)을 가능하게 하는 것에 있다. 이는 코드를 읽기 쉽게 만든다. 17번째 줄에 있는 코드를 보자.

String s = new Student { Name = "Tom", Age = 23 }.ToString().ToUpper();

한 명령문 안에서 다음의 작업을 수행하고 있다.

  1. 매개변수가 없는 생성자인 Student()를 호출하여 Student 객체를 생성한다.
  2. Name, Age 두 프로퍼티를 초기화한다.
  3. 2까지의 결과로 나온 수식 값은 생성한 객체의 참조이다. 이 참조에서 ToStirng()을 호출하고 이어서 ToUpper()를 호출한다.

객체 초기자를 사용하지 않고 작성한다면, 코드의 길이가 늘어나고 가독성을 떨어뜨릴 것이다.