현 블로그는 모바일 환경이 아닌 PC환경에 최적화 되어있습니다.

 Mir의 운영환경

 본체

 DeskTop

 O S

 Windows XP Professional Version 2002 Service Pack 2

 Application

 VisualStudio2010 (Ver.9.0.30319.1)

 .Net

 Framework Ver 3.5

Extension Methods (확장 메소드)


LINQ를 배우기 앞서 .Net Framework 3.0에서 추가된 기능 Extension Methods(확장 메소드)를 배워보자.

(MSDN참조 : https://msdn.microsoft.com/ko-kr/library/bb383977.aspx)

 

이번엔 확장 메소드(Extension Methods)라는 것을 배워보겠습니다.

개인적으로 좀 재밌는 기능이라고 생각하는데 말 그대로 메소드를 확장하는 기능입니다.

(기능을 알고난뒤에는 '아~ 그래서 확장메소드이구나' 하는데 모를때는 '뭘 확장한다는거지?' 라는 생각이 먼저 떠오를겁니다.)

 

확장 메소드(Extension Methods)란?

일반적으로 프로그래머가 정의한 메소드를 호출한다면 [ Class.Method() ] 이런형식으로 호출 한다고 생각합니다.

우선은 Class를 만들고 난뒤 그에 속하는 Method()를 코딩하여 호출하는 방식인데

확장 메소드는 호출시 [ Type.Method() ] 라는 형태를 가지고 있습니다.

Method()를 호출하는데 메소드가 속해있는 Class를 통해서가 아닌 확장 메소드에서 설정한 Type을 통해서 호출이 가능한것입니다.

글로써는 설명하기 조금 힘들어서 간단히 확장메소드를 만들어 보았습니다.

 

 

위 그림을 보면 Int형 a라는 변수를 선언하고 메소드를 호출할려고 리스트를 열어보니 IntTestMethod()라는 메소드가 보입니다.

int형 변수를 다룰때 IntTestMethod()라는 메소드를 본적이 있으신가요?

당연히 기존 Int형 변수에서는 볼수 없던 메소드입니다.

IntTestMethod()는 필자가 확장 메소드란 이런것이다를 보여주기 위한 테스트용 확장 메소드입니다.

 

이제 확장 메소드라는 기능에 대한 이해가 조금은 이해가 되는지요?

다시 한번 말하면 확장메소드(Extension Method)는 변수가 가진 메소드리스트를 확장하여 새로운 메소드를 정의 하는 기능입니다.

 

확장메소드에 대한 개념이 조금은 잡혔다고 생각하며 구현 하는 방법을 알아보도록 하겠습니다.

namespace Extension_Test
{
    public static class Extension_Class
    {
        public static string Extension_Test(this int i)
        {
            return i.ToString();
        }
    }
}

확장메소드는 기본적으로 Static Class에 Static Method로 선언되어야 합니다.

코드를 보면 정적메소드(Static Method)와 별반 차이가 없어 보이지만 매개변수에 this 한정자를 사용하고 있습니다.

이 this한정자가 매우 중요한 포인트인데 이 this 뒤에 오는 Type의 확장메소드가 만들어 지기 때문입니다.

public static void Extension_Test(this int i){}     //Integer형에 대한 확장 메소드
public static void Extension_Test(this string s){}  //String형에 대한 확장 메소드
public static void Extension_Test(this Button b){}  //Button형에 대한 확장 메소드

예를 들어 위 예제 소스에서 [this Int i]를 [this Button i]로 변경하면

 

그림과 같이 Button형의 변수에 해당 확장 메소드가 추가 됩니다.

 

그리고 이 this 한정자 뒤에 있는 매개변수로 확장 메소드를 호출하는 변수가 자동 대입되게 됩니다.

namespace Extension_Test
{
    public static class Util
    {
        /// 
        /// String형을 Integer형으로 리턴합니다. 해당 변수가 Integer형이 아닐경우 def 매개변수값으로 리턴합니다.
        /// 
        /// 변경 String
        /// Default값
        /// Integer
        public static int chint(this string s, int def)
        {
            int temp = 0;
            if (int.TryParse(s, out temp)) { return temp; }
            else { return def; }
        }
    }
}

매개변수로 [string s]와 [int def]를 받는 예제용 Util 메소드를 하나 만들어 봤습니다.

 

캡쳐화면을 보면 필자가 정의한 확장메소드에서는 매개변수가 2개였지만 사용시 하나의 매개변수만 입력하도록 표시됩니다.

그 이유는 확장메소드를 호출하는 변수(b)가 this 한정자가 가르키는 변수 string s에 자동 대입이 되기 때문입니다.

 

 

마지막으로 제약사항을 알아보고 끝내도록 하겠습니다.

 

1. Framework 3.5이상의 버전에서만 동작한다.

(System.Cord.dll 이 참조가 되어야 하는데 3.5이상은 자동참조이지만 그 이하는 강제로 참조 시켜줘야합니다. 

그런데.. 그냥 3.5만드는게 속편합니다.. 억지로 참조시키면 3.5로 왜 안바꾸냐고 막 계속 막...  )

 

2. static Class내의 static Method로 구성되어야 한다. (구현방법에서도 말했습니다.)

 

3. this 한정자가 사용되어야 한다. (필수 조건이며 포인트입니다.)

 

 

확장메소드는 [ Class.Method(s,n) ]를 [ s.Method(n) ]로 표현을 변경할수 있다는 것밖에 없습니다.

굳이 없더라도 기존에 있었던 형식으로 사용할수도 있고 어떻게 보면 개발자를 더욱 복잡하게 만드는 기능일수도 있습니다.

 

하지만 설계측면에서 보면 매우 재밌는 기능이며 효율성을 더욱 높일수 있는 스킬이라고 생각합니다.

using구문 하나로 type에 대한 메소드를 넣고 뺄수 있다는것은 음.. Convert에 관련된 Util을 한 Class에 넣어놓고 필요할때만 부른다 싶으면 개인적으로는 편하고 재밌을꺼 같습니다.

 

그리고 LINQ관련 메소드도 확장메소드가 많습니다.

예를 들어 Framework 3.5이상 프로젝트를 만들고 난뒤 string 변수를 하나만들어서 using System.Linq; 를 넣었다가 뺐다가 하면서 메소드 리스트를 보시면 엄청나게 많은 확장메소드가 생겼다가 사라졌다가 하는 것을 볼수 있습니다.

 


Tip.

※ 관련글

[C#/.Net][Framework 3.0 신규 기능(1)] Implicitly Typed Local Variables (암시적으로 형식화된 지역변수)

[C#/.Net][Framework 3.0 신규 기능(2)] Extension Methods (확장 메소드)

+ Recent posts