LINQ to Object는

IEnumerable<T> interface가 구현된 어떤 Object에서도 사용이 가능합니다.

Non-Generic 타임은 Cast를 통해 쿼리가 가능합니다.

예제를 보죠.

private static void QuetyTest()
{
     string[] names = { "Tom", "Bill", "Harry", "June", "Mary", "Jay" };

     var r01 = from x in names
          where x.Contains("a")
          orderby x.Length
          select x;

     foreach (var x in r01)
     {
          Console.WriteLine(x);
      }
}

형식은 sql을 해봤다면 눈에 살짝 들어올꺼에요.
3번째 줄에서는 사용할 data를 만들었어요(이름들이죠)

5번째 줄~8번째줄에서 data를 가져오는데요
names는 사용할data
x는 그 data에서 한녀석(?)을 의미해요.
(위의 names에 있는 이름들 하나하나 같은거죠.... 음....)

where 뒤쪽이 이제 가져올 data에 대한 조건을 의미하고
Contains("a")는 "a"가 포함되어 있는지 여부를 확인하는 겁니다.

orderby 는 정렬조건인데
orderby x.Length는 x의 길이로 정렬을 한다는 거죠(참 쉽죠잉~  )

이렇게 하면 r01에 해당 data가 들어가 있겠죠.

그 다음에 출력을 해보면
이렇게 나와요.
(이름에 "a"가 들어가 있는 녀석들만 나오는거죠.)

그럼 이제
앞에 포스팅 했던 글에서 말했던
지연실행에 대해 볼께요.

            var numbers = new List();
            numbers.Add(1);

            var r01 = numbers.Select(x => x * 10);

            numbers.Add(2);

            foreach (var x in r01)
            {
                Console.WriteLine(x);
            }

2번째 줄에서 numbers에 1을 넣고.
3번째 줄에서 numbers.select를 해서 값을 가져옵니다.
가져올 값 x는 x*10을 해서요

그러면 r01에는 10이 들어가겠죠?

그 다음에 numbers에 2를 넣어줍니다.

그리고 출력을 합니다.

결과가 어떻게 나올까요?
10 이 나와야 할꺼 같네요.

근데 10과 20이 출력 됐네요...

10과 20이 출력된 이유는 바로
LINQ가 지연실행되기 때문입니다.
1을 넣고 r01에 1*10을 넣었지만.

그때 쿼리가 실행된게 아니라 데이터가 열거되는 시점인
5번째줄~8번째 줄때 쿼리가 실행됐기 때문에
numbers.Add(2)가 포함된 값이 출력된것이죠.

이걸 잘 염두해 두지 않으면
정말로 원치 않는 엉뚱한 결과가 나올수도 있어요.

하지만 (역시 앞에서 말했던 건데요)
이걸 바로 실행되게 할수도 있어요

var r01 = numbers.Select(x => x * 10).ToList();

이렇게 해주면
바로 쿼리가 실행되서
원하는(이걸 원한다면 말이죠) 값이 출력 되겠죠.

글이 너무 길어지면 보기 싫으니
나머지 예제들은 뒤로 보낼께요

출처?는 김수영MVP님의 주말특강입니다
by 피요히코~ 2009. 4. 26. 19:28
| 1 |