현재 시리즈 제목 "LINQ시리즈"이다. 그러나 아직 본격적인 LINQ에는 들어가지도 못하고 있다. 지금 하나씩 설명하고 있는 단위 기술들 델리게이트, 익명 메소드, 제네릭, 타입 유추, 익명 타입 그리고 앞으로도 배울 람다 표현식을 포함한 몇 가지는 그 자체만으로도 가치가 있는 기술들이기는 하지만 뒤에서 설명할 LINQ에서 조합되어서 그 효과를 발휘하게 될 것이다. 그래서 표현식은 아조 아조 심플하게 변하게 된다. 한번 더 볼까나.
var query =
from c in customers
where c.Discount > 3
orderby c.Discount
select new { c.Name, Perc = c.Discount / 100 };
이렇게 간단한 표현속에 그렇게 많은 개념과 기술이 들어가 있을 줄이야. 필자도 미처 몰랐다. 이젠 좀 지겹기는 하다. 할것도 많은데. LINQ에 대한 본격적인 공부도 해야 하고. 그리고 필자의 원래의 목표였던 프레임워크 주제 특히 이번에는 Spring.NET에 대한 공부도 계속 하야 하는데. 그러나 이 표현식을 그냥 대충 넘어갈 수는 없을 것 같다. 완벽히 이해해야 할 것 같다. 그래야 앞으로의 개발자 생활이 편해질 것이라는 것이 필자의 동물적 생존 본능으로 느껴지고 있다. 빠샷!
오늘 Object initializer, 익명타입(anonymous type)이란 것을 함께 알아보자. 이 두 녀석도 철저히 코드를 심플하게 만들기 위한 개념들이다. 객체를 생성할때 그 내부 상태를 특정 상태로 초기화시켜 주고 싶다면 보통 파라미터가 있는 생성자(Constructor)를 사용합니다. 다음과 같은 타입이 있다고 하겠다.
public class Customer
{
public string Name;
public string City;
public int Age ;
public Customer(){}
public Customer(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
Customer의 객체는 name, age 파라미터를 갖는 생성자를 통해서 초기화될 수 있다. 만약 age가 아니라 city값을 초기화하고 싶다면 앞의 생성자 대신에 파라미터가 없는 기본 생성자와 공개적으로 노출된 속성을 통해 설정하는 다음과 같은 코드가 필요하다.
Customer c = new Customer();
c.Name = "Bart";
c.City = "Ghent";
C#3.0부터는 이렇게 객체를 초기화하는 코드를 간단히 할 수 있는 폼을 제공하고 있다.
Customer c = new Customer{ Name = "달봉이", City="Seoul" };
이런 표현을 Object initializer라고 한다. 인자가 없는 기본 생성자와 상태 설정이 필요한 값을 공개 속성 또는 필드로 노출시켜 두면 된다. 이 코드는 컴파일되어 IL코드로 되면 앞의 코드의 컴파일 결과와 동일해진다. {}사이에 명시된 이름들은 초기화되는 객체에서 공개적으로 노출한 속성 또는 필드에 해당한다.
앞에서처럼 타입과 시작 브래킷{ 사이에 ()이 없는 경우는 기본 생성자를 호출한다. 그러나 인자가 있는 생성자를 호출할 수도 있다.
// 파라미터가 있는 생성자를 초기화에 사용할 수도 있다.
Customer c = new Customer( "달봉이", 100 ) { City="Seoul" };
object initializer를 사용하면 함수 형태로 객체 초기화를 마무리할 수 있다. 즉 다른 문장을 사용하지 않고도 하나의 문장으로 복잡한 초기화를 끝낼 수 있다. 다음 코드를 보자.
Customer c = new Customer{
Name = "Bart",
Age = 23,
Address = new Address {
Street = "Andersstreet",
Number = 60,
PostalCode = 9000,
City = "Ghent"
}
};
이렇게 객체안에 포함된 다른 객체의 초기화 코드도 하나의 문장으로 마무리될 수 있다. 이 표현도 다시 간단하게 변할 수 있는데, 내부의 중첩된 객체의 생성에서는 new를 없앨 수 있다. 최외곽의 생성자에서만 new를 사용해도 된다.
Customer c = new Customer{
Name = "Bart",
Age = 23,
Address = {
Street = "Andersstreet",
Number = 60,
PostalCode = 9000,
City = "Ghent"
}
};
C#1.X에서도 이런 비슷한 표현이 있었다. 그러나 배열 생성에만 제한되어 있었다.
string[] names = {"달봉이", "봉달이", "봉봉이"};
이런 표현의 initializer는 컬렉션에서 자주 사용된다.
List<Customer> list = new List<Customer>{
new Customer("달봉이", 100){ City = "Seoul"},
new Customer{Name="봉달이"},
new Customer{ Name = "봉봉이" City = "Seoul"},
};
요약하면, LINQ에서는 주로 그 쿼리의 대상들이고 그리고 그 쿼리 결과도 컬렉션으로 반환되는 경우가 많다. object initializer 표현은 LINQ에서 광범위하게 사용된다. 익명 타입(anonymous type)은 objct initializer로 인해서 심플해진 표현을 더 심플하게 해 준다.
포스트가 너무 길어진다. 익명 타입은 다음 포스트로 넘기자.
'IT 살이 > 04. 기술 - 프로그래밍' 카테고리의 다른 글
LINQ 시리즈 06 - Object initializer, 익명 타입(anonymous types) II (0) | 2009.04.23 |
---|---|
LINQ 시리즈 04 - type inference( 타입 유추 ) (0) | 2009.04.23 |
LINQ 시리즈 03 - 제네릭(Generics) (0) | 2009.04.23 |