객체를 생성한 후 그 객체의 접근할 수 있는 프로퍼티 또는 (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();
한 명령문 안에서 다음의 작업을 수행하고 있다.
- 매개변수가 없는 생성자인 Student()를 호출하여 Student 객체를 생성한다.
- Name, Age 두 프로퍼티를 초기화한다.
- 2까지의 결과로 나온 수식 값은 생성한 객체의 참조이다. 이 참조에서 ToStirng()을 호출하고 이어서 ToUpper()를 호출한다.
객체 초기자를 사용하지 않고 작성한다면, 코드의 길이가 늘어나고 가독성을 떨어뜨릴 것이다.