확장 메서드 만들기

  • 7 minutes to read

우리는 앞서 닷넷 API를 다루면서 많은 양의 확장 메서드(Extension Method)를 이미 사용해 보았습니다.

이번 강의는 이러한 확장 메서드를 직접 만들어보는 시간을 갖도록 하겠습니다.

> // 확장 메서드: 기존 형식에 메서드를 추가하는 기능으로 확장 형식의 인스턴스 메서드로 사용

확장 메서드

확장 메서드(Extension Method)는 원본 형식을 변경하지 않고 이미 있는 형식에 추가적인 기능을 덧붙일 수 있습니다. 클래스, 구조체, 인터페이스에서 확장 메서드를 사용할 수 있습니다. 확장 메서드는 이미 만들어 있는 클래스의 기능을 확장하는데 사용됩니다. 특히, 봉인(Sealed) 클래스는 상속이 불가능하므로 봉인 클래스에 새로운 메서드를 적용할 때도 유용합니다.

확장 메서드 만들기

확장 메서드는 static 키워드가 붙은 클래스에 static 메서드로 만들어집니다. 이때 반드시 동일한 네임스페이스가 참조되어야 합니다. 확장 메서드의 첫 번째 매개변수에 this 키워드를 지정하여 확장 메서드를 사용할 개체의 형식을 지정할 수 있습니다. 확장 메서드를 사용하면 같은 네임스페이스의 모든 클래스에서 해당 확장 메서드를 호출해서 사용할 수 있는데, 확장 메서드는 이미 완성되어 사용 중인 기존 형식에 새로운 메서드를 추가하는 방법으로 사용됩니다.

확장 메서드의 메서드 시그니처는 다음과 같이 표현하는데, 첫 번째 매개변수는 직접 넘겨주는 게 아닌 정적 메서드로 호출될 때 호출할 개체의 형식을 표현합니다.

> public static void MethodName(this object obj, int i) { }
> public static void MethodName(this string str, int i) { }

확장 메서드 만들기는 다음 단계로 이루어집니다.

  • 확장 메서드는 반드시 정적 클래스 안에 정적 메서드로 만들어야 합니다.
  • 메서드의 첫 번째 매개변수 앞에 this 키워드를 붙여서, 해당 형식의 개체에 새로운 메서드를 추가할 수 있습니다.
  • 같은 네임스페이스 안에서만 확장 메서드를 호출할 수 있고, 범위도 동일해야 합니다.
  • 확장 메서드는 이름은 같지만 매개변수를 다르게 받는 여러 버전을 만들 수 있습니다. 이를 오버로딩이라고 합니다.

확장 메서드로 문자열 기능 확장하기

우선, 확장 메서드를 만들고 사용해 보겠습니다.

사용자 정의 형식이 아닌 기본 형식인 string, int, char 등의 데이터 형식에 새로운 기능을 추가해 보겠습니다.

코드: ExtensionFunction.cs

using System;

static class ExtensionFunction
{
    // static 클래스안에 static 메서드의 첫번째 매개 변수에 this가 붙은 것은 확장 메서드
    static string Three(this string value)
    {
        // 특정 문자열 뒤에 이 메서드가 호출되면 문자열 중 3개만 반환 
        return value.Substring(0, 3);
    }

    static void Main()
    {
        Console.WriteLine("안녕하세요.".Three());
    }
}
안녕하

코드내의 주석에 설명한 것처럼 static 클래스에 static 메서드를 만들고 메서드의 첫 번째 매개 변수에 this를 붙이면 확장 메서드가 됩니다. Three() 메서드는 특정 문자열(string) 뒤에 붙이면 해당 문자열 중에서 앞에서 3자만 반환해주는 기능을 제공합니다.

확장 메서드를 사용하여 기존 형식에 새로운 메서드 추가하기

이번에는 확장 메서드의 또 다른 사용 예제를 사용해보겠습니다.

코드: ExtensionMethodDemo.cs

//[?] 확장 메서드: 기존 형식에 새로운 메서드를 추가하는 방법
using System;

namespace ExtensionMethodDemo
{
    // static 정적(고정) == shared(공유)
    public static class MyClass
    {
        /// <summary>
        /// 특정 문자열의 단어 개수
        /// </summary>
        /// <param name="str">문자열</param>
        /// <returns>단어 개수</returns>
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' },
                StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }

    class ExtensionMethodDemo
    {
        static void Main()
        {
            string s = "안녕하세요? 확장 메서드... ...";
            Console.WriteLine(s.Length); // [1] 문자의 개수
            Console.WriteLine(s.WordCount()); // [2] 단어의 개수
        }
    }
}
20
3

문자열 변수 s에는 원래 WordCount()라는 메서드가 존재하지 않지만 같은 네임스페이스에 정의된 MyClassWordCount() 확장 메서드를 s 변수에서 사용할 수 있게 된 것입니다.

확장 메서드를 사용하여 형식에 메서드를 추가하기

다음 코드의 Original 클래스는 아무런 멤버를 가지고 있지 않은 클래스이지만, OriginalExtension 클래스에서 NewMethod()에서 참조해서 새로운 메서드를 추가하여 사용하는 예를 보여줍니다.

코드: ExtensionMethodNote.cs

using System;

public class Original { /* Empty */ }

public static class OriginalExtension
{
    public static void NewMethod(this Original original) 
        => Console.WriteLine("새로운 메서드 추가");
}

class ExtensionMethodNote
{
    static void Main()
    {
        (new Original()).NewMethod(); // 확장 메서드 호출 
    }
}
새로운 메서드 추가

참고로, Visual Studio에서 NewMethod()를 작성할 때 인텔리센스에서 아이콘 모양을 보면 일반적인 메서드 아이콘과 다르게 표시됩니다.

장 요약

LINQ에서 제공하는 수많은 메서드들은 확장 메서드로 구성되어 있습니다. 이러한 확장 메서드만 사용해도 일반적인 프로그래밍은 가능합니다. 이번 강의는 이미 있는 확장 메서드가 아닌 나만의 확장 메서드를 직접 만들어보았습니다.

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com