확장 메서드(Extension Method)
 
이름만 들어보아도 뭔가 심오한 분위기가 물씬 풍긴다.
쉽게 말하자만, 기존의 클래스를 확장한다고 해야할까?
만약, 클래스의 메서드를 확장하기 위해선 상속을 하고, 상속한 클래스에서 메서드를 선언하여 확장하는 방식이었다.
하지만 Framework 3.0 에서는 더 이상 메서드의 확장을 위해 클래스의 상속이 필요가 없다.
 
 
시작하기
 
심플한 샘플부터 보도록 하자.
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleTest1
{
        class Program
        {
               static void Main(string[] args)
               {
                       string url = "http://umc.pe.kr";
 
                       Console.WriteLine(url.GetUrl());
               }
        }
 
        public static class MyExtension
        {
               public static string GetUrl(this string url)
               {
                       return string.Format("<a href='{0}'>{0}</a>", url);
               }
        }
}
[코드1] 확장 메서드 사용예

 
 
 
 
public static class MyExtension
{
        public static string GetUrl(this string url)
        {
               …
        }
        ...
}
 
보시다시피 클래스와 메서드는 모두 static 으로 선언이 되었다.
 
MyExtension 클래스의 GetUrl 은 this string url 과 같이 1개있는 메서드다.
이것은 메서드를 확장할 타입이다. 즉, 우리는 string 을 확장한다는 표현인 것이다.
 
그렇다면 인자값을 받는 메서드를 확장해 보자.
 
 
확장 메서드는 반드시 static class 로 만들어야 한다.
그렇지 않으면 다음과 같은 오류 메시지를 맛보게 될 것이다.
 
 
보다시피, this string url 은 확장할 타입이라고 말한 바 있다.
바로 그 뒤로부터 비로서 확장 메서드의 인자값을 받을 수 있다.
 
 
그렇다면 어디까지 확장이 가능한가?
 
“단순히 클래스의 메서드만을 확장하는 것일까” 하고 이부분이 가장 궁금했다.
바로 delegate….
물론 delegate 란 것이, 특정 메모리 상의 위치를 참조하고 있고, 추가적인 동기/비동기 메커니즘 메서드를 제공하고 있다.
 
우선 답은 ‘가능하다’ 이다…
그렇다면 소스를 보자.
 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace ExtensionAsyncMethod
{
        public delegate object BeginRunHandler();
        public partial class Form1 : Form
        {
               public Form1()
               {
                       InitializeComponent();
               }
 
               private void button1_Click(object sender, EventArgs e)
               {
                       // 확장 델리게이트 생성
                       BeginRunHandler handler = new BeginRunHandler(Running);
                       // 확장 메서드 호출
                       handler.BeginRun(new AsyncCallback(EndCallback), handler);
                      
               }
 
               private object Running()
               {
                       // 특정 작업
                       System.Threading.Thread.Sleep(1000);
 
                       return "작업완료";
               }
 
               // 콜백 메서드
               private void EndCallback( IAsyncResult result )
               {
                       BeginRunHandler handler = (BeginRunHandler)result.AsyncState;
                       object objResult = handler.EndRun(result);
 
                       MessageBox.Show(objResult.ToString());
               }
        }
 
        public static class MyExtension
        {
               public static IAsyncResult BeginRun(this BeginRunHandler handler, AsyncCallback callback, object obj)
               {
                       return handler.BeginInvoke(callback, obj);
               }
 
               public static object EndRun(this BeginRunHandler handler, IAsyncResult result)
               {
                       return handler.EndInvoke(result);
               }
        }
}
[코드2] 델리게이트 확장 메서드

 
델리게이트를 생성 후에,
 
handler.BeginRun(new AsyncCallback(EndCallback), handler);
 
 
구문을 통해 델리게이트의 확장 메서드를 호출 할 수 있는 것을 볼 수 있다.
 
 
마치며…
 
정말이지 C# 2.0 에서 3.0 의 변화에서만 볼 수 있듯이, 이렇게 까지 언어적인 설계가 가능한 것만 보아도, 엄청난 아키텍쳐 포스가 느껴진다.
Framework 3.0… 다가갈수록 그 매력이 느껴지지 않는가?
너무나무 눈깜짝할 사이 Framework 3.5 가 떡하니 기다리고 있지만,
차근차근 스텝바이스텝… 기다리거라^^
Posted by 땡초 POWERUMC

댓글을 달아 주세요