2013. 9. 10. 14:30

마이크로 소프트나 다른 회사에서 만든 컴포넌트들을 쓰다 보면 흔히 격는 일 중에 하나가 제공되지 않는 기능이 필요할 때입니다.

보통은 해당 클래스를 상속받는 클래스를 만들거나 별도의 클래스를 만든 후 그 클래스 안에 기존 클래스를 생성하고 새로 만든 클래스에 기능을 추가 하는 방법도 있습니다.

 

그런데 일관성을 높이려면 A클래스에 속한 기능을 B클래스를 선언해서 사용하는 건 그리 좋은 방법이 아닙니다.

기존에 A클래스를 참조하고 있는 모든 기능을 B클래스로 옮겨야  하기 때문이죠.

(안 그러면 어떤 건 A를 참조하고 어떤 건 B를 참조하는 불상사를 많이 보게 됩니다-_-;)

 

이럴 때 사용하는 것이 확장 메서드(Extension Methods) 입니다.

이름 그대로 남이 만들어 놓은 객체에 내가 원하는 기능을 갖다 붙이는 겁니다!

 

1. 확장 메서드의 이해

진짜로 확장 메서드의 기능은 다른 객체에 내가 만든 기능을 추가하는 것뿐입니다.

 

이렇게 확장 메서드를 만들어 두면 'claA'를 참조했을 때 'GetData2()'도 사용할 수 있습니다.

(참고 : MSDN - 확장 메서드(C# 프로그래밍 가이드))

 

 

2. 사용 방법

확장 메서드를 사용하려면 원본 개체가 있어야 합니다.

여기서는 'claA'를 원본 개체로 보겠습니다.

 

2-1. 원본 개체 만들기

원본 개체를 만들 때 네임스페이스를 잘 보시기 바랍니다.

namespace ExtensionMethods.Original
{
	public class claA
	{
		public string Data1 { get; set; }
		public string Data2 { get; set; }


		public void SetData(string sData1, string sData2)
		{
			Data1 = sData1;
			Data2 = sData2;
		}

		public string GetData1()
		{
			return Data1 + Data2;
		}

	}
}

 

원본 클래스를 만들 때 네임스페이스를 따로 지정했습니다.

 

 

2-2. 확장 메서드 만들기

확장 메서드를 만들 때 네임스페이스를 주의해야 합니다.

꼭 원본 객체와 같은 네임스페이스에 있어야 합니다.

만약 다른 네임스페이스에 넣고 싶으면 네임스페이스 안에서 원본 네임스페이스를 유징(using) 해주셔야 합니다.

namespace ExtensionMethods.Original
{
	public static class claB
	{
		public static string GetData2(this claA a)
		{
			return string.Format("{0} {1}", a.Data1, a.Data2);
		}
	}
}

 

 

확장메서드는 항상 '스테틱(static)'으로 선언됩니다.

 

확장 메서드에는 한가지 특이점이 있는데 메서드의 매개변수에 원본 개체를 지정해야 합니다.

원본 객체는 ' this'로 지정합니다.(string GetData2(this claA a))

 

확장메서드는 보기에만 해당 객체의 맴버로 보이는 것이고 실제로는 별도의 개체입니다.

그렇기 때문에 접근 한정자의 제약은 일반 객체들과 똑같이 받습니다.

(원본에 'protected'같은 접근 한정자를 읽을 수 없다는 이야기입니다.)

 

 

3. 테스트

윈폼 프로젝트를 생성하고 버튼을 하나 만들어 테스트해 봅시다.

(어차피 동작은 볼 필요가 없으니 대충 만드셔도 됩니다.)

 

먼저 원본 클래스인 'claA'만 만든 후 폼에서 'claA'의 인스턴스를 만든 후 인텔리전스를 봅시다.

 

'claA'의 메서드인 'GetData1()'만 보입니다.

 

이제 'claB'를 만들고 빌드를 한 다음 다시 확인해 봅시다.

 

'claB'에서 확장한 'GetData2()'가보입니다.

확장 메서드는 설명에 '(확장)'이라고 표시됩니다.

 

 

마무리

정형적인 별거 없는데 MSDN에 복잡하게 나온 기능입니다-_-;;;

물론 기능 자체가 중요하고 예외적인 상황이 많기 때문이니 이해는 갑니다만....

 

어찌됐건 알아두면 유용한 기능인데 실제로 특별한 경우(MS에서 만든 개체라던가...)가 아니면 일부러 쓰는 경우가 많지는 않습니다;;

(그냥 클래스에 원본 개체를 선언한 클래스 만들어서 사용함;;)

 

테스트에 사용한 프로젝트 파일입니다. 

ExtensionMethods.zip
다운로드