본문 바로가기

LINQ

C#, yield return ※ 일단 "yield"는 "항복"보다는 "produce"라는 의미로 해석하자. C# 2.0에서 봤던 것 같은데, "yield return", 이런 녀석이 있구나 하고 그냥 넘어갔었다. 이 녀석을 다시 보게 된 것은 LINQ 때문이다. 그때 정리 좀 해야겠다 싶었던 LINQ의 "Deferred Execution"특성이 "yield return"과 연관되어 있다는 것을 느꼈다. yield return을 이해하면 도움이 될 것 같다는 생각을 했다. ■ yield return 이란 뭣인가? 지금까지 봐온 봐로는 yield return은 주로 컬렉션의 iterator를 구현할 때 이용하는 듯 하다. 다음과 같이 컬렉션이 있다고 해 보자. private static readonly string[] StringVal.. 더보기
LINQ 시리즈 10 - 쿼리 표현식(Query expression) 이해 이제 앞에서부터 계속 사용해온 쿼리 표현식을 이해해보자. Customer[] customers = GetCustomers(); //Query expression var query = from c in customers where c.Discount > 3 orderby c.Discount select new { c.Name, Perc = c.Discount / 100 }; C# 컴파일러는 쿼리 표현식을 만나면 C# 의 클래스와 인터페이스를 사용하는 표현으로 전환한다. // C# 표현 var query = customers .Where ( c => c.Discount > 3 ) .OrderBy( c=>c.Discount ) .Select ( c=> new { c.Name, Perc = c.Discount .. 더보기
LINQ 시리즈 09 - type inference(타입 유추) 좀 더 타입 유추가 어떻게 일어나는지 그 프로세스에 대한 설명을 하지 않고 지날 수 있기를 바랐는데, 그렇게 되지 못했다. 앞 포스트에서 말한대로 이번 포스트는 타입 유추대한 좀 더 자세한 과정을 알아보도록 한다. 타입 유추가 왜 일어나야 하는가. CLR은 타입 유추를 못하기때문이다. C#이 컴파일하고 나서 코드가 CLR로 넘어가기 전에는 모든 변수, 인자, 파라미터들의 타입이 결정되어 있어야 한다는 것이다. 해서 타입이 지정되지 않은 람다 표현식이 제네릭 메소드의 인자로 넘겨지면 컴파일시 타입 유추가 수행되어야 한다는 것이고 그 유추 과정을 같이 한번 더듬에 보자는 것이 이번 포스트 내용이다. 앞에서 본 코드이다. public static void Display(T[] names, Func filter) { .. 더보기
LINQ 시리즈 08 - 메소드 확장( Extension Methods) 객체 지향을 지원하는 언어에서 타입을 확장하는 방법하면 제일 먼저 떠오르는 것은 바로 상속(inheritance)에 의한 메소드의 오버라이딩 또는 오버로딩 또는 하이딩(hinding)이다. 혹시 이 세가지 개념이 구분이 잘 가지 않는다면 구글링을 한번 해 보자. 여튼 타입 확장 하면 상속이라는 것이 제일 먼저 떠오르는 것은 당연하다. 근데 C#3.0부터 새로운 확장 방법을 제공하고 있으니 "메소드를 확장"할 수 있다는 것이다. 즉 사용자 정의 메소드를 마치 원래의 그 타입의 메소드에서 정의한 것처럼 호출해서 사용할 수 있다는 것이다. 클래스에 Sealed로 해서 상속을 허락하지 않는 타입에서도 이런 메소드를 확장하는 방법이 가능하다. C#의 이런 능력은 LINQ문이 좀 더 읽기 쉽고 코딩하기 쉽게 해준다.. 더보기
LINQ 시리즈 07 - 람다 표현식(lamda expressions) 람다 표현식. 참 이름도 신기하다. 이 녀석을 뭔지 미리 말하면 이렇다. 델리게이트가 사용될 자리에서 매우 심플한 표현으로 대신할 수 있는 녀석이다. Customer[] customers = GetCustomers(); //LINQ 쿼리문 var query = from c in customers where c.Discount > 3 orderby c.Discount select new { c.Name, Perc = c.Discount / 100 }; // C# 표현 var query = customers .Where ( c => c.Discount > 3 ) .OrderBy( c=>c.Discount ) .Select ( c=> new { c.Name, Perc = c.Discount /100 } ); .. 더보기
LINQ 시리즈 03 - 제네릭(Generics) 제네릭이 뭔지 알아본다. LINQ 표현에 제네릭이 직접 표현되지 않더라도, C# 표현으로 변경하면 보이지 않던 제네릭 표현이 나타나게 된다. C# 표현의 쿼리를 이해할 수 있어야 LINQ 표현을 정확히 이해할 수 있는 바, 이 녀석을 모르고서는 LINQ 표현을 제대로 이해할 수 없다는 얘기가 되겠다. 다음과 같은 상황을 생각해보자. 메소드나 클래스를 정의할때 그 구성 요소에 대한 타입을 미리 알 수 없을때, 즉 여러 타입을 지원하고 싶을때 어떻게 해야 하나. object 타입을 사용하면 될 거라고 생각하고 있나. C# 1.X까지는 정답이다. 다음은 IList 타입의 컬렉션의 Add() 메소드에 대한 정의이다. public interface IList : ICollection, IEnumerable { i.. 더보기
LINQ 시리즈 02 - 익명 메소드(anonymous method ) 앞의 포스트에서 다음 코드를 보았다. delegate void SimpleDelegate(); public class Writer { public string Text; public int Counter; public void Dump() { Console.WriteLine(Text); Counter++; } } public class DemoDelegate { void Repeat10Times(SimpleDelegate somework) { for (int i = 0; i < 10; i++) somework(); } void Run1() { Writer writer = new Writer(); writer.Text = "C# demo"; this.Repeat10Times(writer.Dump); Con.. 더보기
LINQ 시리즈 01 - 델리게이트(delegate ) 앞에서 얘기한대로 이제 C#언어에 대해서 알아보겠다. LINQ 쿼리문을 이해하기 위해서 필요한 C#언어 요소들을 하나씩 알아가보겠다. 먼저 델리게이트 ! 델리게이트하면 필자에게는 다음과 같은 내용이 떠오른다. ▶클래스와 같은 일종의 타입이다. 다음과 같은 방법으로 델리게이트 타입을 정의한다. delegate void TwoParamsDelegate(string name, int age); ▶이것도 타입이니 인스턴스를 만들 수 있다. TwoParamsDelegate c = new TwoParamsDelegate(인자); ▶델리게이트 타입의 객체에는 다른 객체의 메소드에 대한 포인터가 할당된다. 앞의 TwoParamsDelegate 델리게이트 타입은 파라미터로 string, int 타입의 값을 받고 void.. 더보기
LINQ 시리즈 00 - 들어가기 Application Block같은 .NET용 개발 프레임웤을 보면 이제 제너릭 정도는 자연스럽게 사용되고 있다. 프레임웤에 대한 공부를 더 진행하기 전에 이쯤해서 C#에 대한 정리를 해야 할 것 같다. 그러나 하는 김에 제너릭뿐만 아니라 C#3.0이상에서 소개하고 있는 표현들에 대한 정리도 해 볼려고 한다. 그러나 필자도 아직 다 공부를 못한 부분이기에 시간이 좀 걸려서 진행될 것 같은 분위기다. 이번 포스트부터도 연재 형태로 갈려고 한다. 최종 목표는 LINQ라는 것의 이해이다. 해서 연재 제목을 이름하여 "LINQ 시리즈"로 정했다. 들어가기 전에 먼저 하나 생각해 보도록 하자. 고객이 여러명 있다. 이 고객들에 대한 정보가 어떤 형태로 있을 수 있을까? 우선 Customer라는 사용자 정의 타입이.. 더보기