C#3.0이 등장 하면서 여러 가지 새로운 기능이 추가 되었습니다. 타입유추, 익명타입, 람다 표현 식, 개체/컬렉션 초기화, Nullable 타입, 확장 매서드, 쿼리키워드, 자동으로 구현된 속성(Automatic Property, 부분 매서드(partial method) 등등 상당히 많은 새로운 기능들이 추가 되었습니다. 이 기능 중 대부분의 기능은 LINQ의 기반이 되며 LINQ를 배우기 이전에 먼저 학습할 필요가 있습니다.

 

이번 강좌를 시작으로 앞에서 언급한 새로운 기능 중 LINQ의 기반이 되는 새로운 기능들에 대해 강좌를 연재 하려고 합니다. 언제 강좌가 마무리 될지 확실하지는 않지만 최대한 주기적으로 강좌를 연재하고 최대한 빠른 시간 안에 마무리 하도록 노력하겠습니다.

 

C# 3.0부터 지역 변수의 타입을 반드시 명시적으로 지정해줄 필요 없이 var키워드를 사용하여 컴파일러가 타입을 유추할 수 있도록 할 수 있습니다. 이는 뒤에서 배우게 될 명시적으로 타입을 지정하지 않는 익명 타입이나 가독성이 떨어지는 중첩된 제네릭(: IEnumerable<IEnumerable<Product>>)  같이 특수한 경우에 var키워드를 사용하여 좀더 간단하게 타입을 표현할 수 있습니다.

다른 개발자가 코드를 보았을 때 이해 할 수 있는 수준으로 작성이 되면 var키워드를 통한 타입 유추는 좀더 간결한 코드를 만들어 낼 수 있는 훌륭한 기능이라 할 수 있겠습니다.

 

1.    타입유추는 어떻게 이루어 지는가?

var키워드는 변수를 선언하고 그 값을 할당하는 초기화 구문에서 ‘=’을 기준으로 오른쪽 부분의 형태에 따라 컴파일러에게 타입유추를 지시 하게 됩니다.

 

var i = 5

 

위의 코드를 보면 5라는 값이 변수 i에 할당되므로 컴파일러는 5라는 값이 숫자 즉 int타입이라는 것을 미리 알고 있기 때문에 변수 i int타입으로 유추하게 되는 것 입니다.

 

//string타입으로 유추

var s = “Taeyo.NET”;

//double타입으로 유추

var d = 12.5;

//char타입으로 유추

var c = ‘k’;

 

C#의 기본 타입 뿐만 아니라 사용자 정의 타입(Class) 및 익명 타입(Anonymouse Type) 또한 유추 될 수 있습니다.

 

그럼 간단하게 사용자 정의 타입(Class)을 유추하는 코드를 살펴 보도록 하겠습니다.

 

Class Person

{

     public string FirstName;

     public string LastName;

     public int Age;

}

 

Person person = new Person();

person.FirstName = “경균”;

person.LastName = “”;

person.Age = 19;

 

//사용자 지정 타입으로 유추

var p = person;

 

Person이라는 새로운 Class를 만들고 개체를 생성한 후 var 키워드로 선언된 p라는 변수에 person개체를 할당하게 되면 컴파일러에 의해 변수 p Person타입으로 유추 됩니다.

 

익명 타입 또한 컴파일러에 의해 유추가 가능 합니다.

아래 코드를 보면 식의 오른쪽 부분이 익명 타입이고 그 타입을 변수 p가 받게 되면 컴파일러에 의해 변수 p는 익명 타입으로 유추가 됩니다.

 

//익명타입으로 유추

var p = new { FirstName = “경균”, LastName = “”, Age = 19 };

 

위의 예제 코드에서는 익명타입의 형태만 알아 두고 자세한 내용은 다음 강좌에서 자세히 알아 보도록 하겠습니다.

 

다음은 쿼리표현식의 타입을 유추하는 코드 입니다.

 

// IEnumerable<Product>타입으로 유추

var products =

    from p in Products

    where p.ProductName == "chai"

    select p;

위의 쿼리 표현식은 LINQ를 활용함에 있어서 가장 많이 사용되는 구조입니다. 코드에 대해 간단히 알아보면 Products테이블에서 ProductName‘Chai’와 같은 상품을 출력하는 구문으로 그 결과는 IEnumerable<T>타입입니다. 그렇기 때문에 products변수는 IEnumerable<T>타입으로 유추 됩니다. 쿼리 표현식은 마지막 강좌에서 자세히 다루도록 할 것입니다.

 

2.    정말로 유추를 하는가?

간단한 예제 코드를 컴파일 하고 실제 어떻게 타입유추가 일어나는지를 확인 하기 위해 IL DisAssembler(ildasm.exe)를 사용하여 컴파일된 IL코드를 확인 해 보도록 하겠습니다.

 

아래는 Int타입과 직접 작성한 Person타입을 이용하는 예제 코드 입니다.

 

Class Person

{

     public string FirstName;

     public string LastName;

     public int Age;

}

 

class TypeInference

{

        public int GetInt()

        {

            var i = 10;

            int b = 11;

                var p = new Person();

            return i;

        }

}

 

타입유추를 테스트 하기 위해 변수 ivar키워드를 통해 초기화 했고 변수 b는 일반적인 방식으로 int타입으로 선언 하였습니다. 그리고 사용자 정의 타입인 Person타입을 변수 p에 할당 했습니다.

위의 코드를 컴파일 한 후 IL DisAssembler를 사용해 IL코드를 확인 해 보면 아래와 같은 코드를  볼 수 있습니다.

 

 

변수 i와 변수 b 모두 int32형태로 초기화 된 것을 확인 할 수 있으며 변수 p는 정확히 Person타입으로 유추된 것을 확인 할 수 있습니다.

 

3.    var키워드의 사용 범위

 

var키워드는 아무데서나 사용할 수 있는 것은 아닙니다. 매서드 내부의 지역변수나 for, foreach, using문의 초기화 구문에서 사용될 수 있습니다.

 

매서드 내의 지역변수로서 사용

public int GetTotalCount()

{

     var cnt = db.TotalCount();

     return cnt;

}

 

for문의 초기화 구문에서 사용

for(var i = 0 ; i <10 ; i++){…}

 

foreach문의 초기화 구문에서 사용

foreach(var dr in dt.Rows){…}

 

using문의 초기화 구문에서 사용

using(var file = new StreamReader(“c:\test.txt”)){….}

 

4.    var키워드를 사용하면서 이것만은 주의하자.

var키워드는 자바스크립트나 VBVariant”로 오해 할 수 있습니다. 하지만 C# var키워드는 런타임에 바인딩 되지 않고 컴파일 타임에 컴파일러가 적합한 타입을 결정하고 할당하게 됩니다.

그렇기 때문에 컴파일러가 적합한 타입을 결정하려면 선언과 동시에 초기화가 이루어 져야 하며 Null은 사용할 수 없습니다.(Null은 타입이 없기 때문이죠) 또한 클래스 범위에서는 사용할 수 없고 반드시 매서드 내의 지역변수로 사용해야 합니다.

 

var키워드의 상당히 편리하지만 명시적으로 타입이 선언되어 있지 않기 때문에 다른 개발자가 코드를 보게 되면 코드를 이해하기 난해 할 수 있습니다. var키워드를 반드시 필요한 경우(익명타입, 쿼리표현식의 결과타입, 중첩된 제네릭 타입 등)에 사용하면 보다 나은 개발 편의성 및 생산성 향상에 도움이 될 것입니다. 타입유추는 LINQ를 사용하기 위해 반드시 알아야 할 중요한 내용이기 때문에 첫번째 강좌에서 이렇게 다루었습니다. 다음 강좌는 익명타입 과 개체/컬렉션 초기화에 대해 알아 보도록 하겠습니다.

감사합니다.

 

이올린에 북마크하기(0) 이올린에 추천하기(0)
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by kyeongkyun(kobukii) kyeongkyun
이전버튼 1 이전버튼