본문 바로가기

IT 살이/04. 기술 - 프로그래밍

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 시리즈 06 - Object initializer, 익명 타입(anonymous types) II 앞의 포스트에서 Object initializer에 대해서 알아봤다. 먼저 읽어보는 것이 좋을 듯 싶다. 이제 익명 타입(anonymous types)을 알아보자. C#3.0부터는 다음과 같은 표현이 가능해진다. Customer c1 = new Customer{ Name="달봉이"}; var c2 = new Customer{Name="봉달이"}; var c3 = new {Name="봉봉이", Age=30 }; var c4 = new {c2.Name, c2.Age }; var c5 = new { c1.Name, c1.City}; var c6 = new {c1.City, c1.Name}; c1 생성은 앞에서 배운 객체 초기화 코드이다. c2는 Customer 객체를 초기화해서 var 타입에 할당하고 있다. .. 더보기
LINQ 시리즈 05 - Object initializer, 익명 타입(anonymous types) I 현재 시리즈 제목 "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 시리즈 04 - type inference( 타입 유추 ) C#(3.0이상)의 타입 유추(type inference)는 쿼리 표현을 단순하게 만드는데 있어서 핵심적인 역할을 하는 기능중의 하나이다. 쉽게 말하면 변수의 타입을 정확히 명시하지 않고도, 앞 뒤 표현 문맥을 통해서 그 변수의 타입을 유추해 낼 수 있는 기능이다. 이 기능을 이용하면 변수의 타입에 대해서는 좀 덜 명확하게 되기는 하지만 "코드"가 좀 더 자연스런 언어처럼 된다. 여기서 "코드"란 쿼리 표현(query expression)을 말한다. 즉 쿼리 표현에서 처럼 자연스러움 즉 읽기 편함(readability)이 중요하고 명확한 타입 선언이 반드시 필요한 곳이 아니라면 타입 유추 기능은 의미를 갖게 된다. 사실 타입 유추 자체만으로는 그렇게 큰 의미가 없는 듯하다. 그러나 언어의 다른 기능과 함.. 더보기
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라는 사용자 정의 타입이.. 더보기
BindingContext - Load() vs. LoadFrom() 달봉이가 가끔 부딪치고 있는 두 개념 LoadContext와 LoadFromContext에 대해서 정리해 볼까 한다. Loaded Assembly Cache 바인딩 컨텍스트(binding context)라는 것이 있는데, Junfeng Zhang(이 사람 이름은 어떻게 발음해야 할지 달봉이는 항상 고민이다)에 의하면 로딩된 어셈블리의 캐시(loaded assembly cache)로 말하고 있다. 우리가 익히 알고 있는 GAC(Global assembly cache)도 바인딩과 프로빙 과정을 거치지 않도록 할 수 있다는 점에 어떻게 보면 캐시라고 볼 수도 있을 것이다. 그리고 NTD에 의해 배포된 어셈블리가 캐싱되는 어셈블리 다운로드 캐시(assembly download cache)도 있다. 허나 이런 캐.. 더보기
위성어셈블리 반복 요청 최적화 1. 문제 제기 NTD타입의 스마트클라이언트 애플리케이션을 개발하면서, 서버로 어셈블리를 요청하는 과정을 모니터링하다 보면 다음과 같은 화면을 볼 수 있다. 리소스 어셈블리반복 요청 어셈블리를 하나 요청하면 그것과 관련해서 추가적인 요청이 여러번 반복된다. 이런 추가적인 요청이 로컬 PC에서만 일어난다면 모를까 원격에 있는 서버에 어셈블리를 요청할때마다 반복적으로 일어난다면 성능에 영향을 끼칠 수 있다. 이번에는 이런 현상이 왜 일어나는지 알아보고 방지하거나 최적화하는 방안에 대해 생각해 볼 것이다. 이런 현상은 .NET이 리소스를 관리하는 방식때문인데, 리소스 관리는 애플리케이션의 Globalizaion&Localization과 관련된 주제다. 2. Globalization(전역화) & Localiza.. 더보기