개요
확장 메서드(Extension Method)가 뭘까
확장 메서드는 기존에 존재하던 클래스의 기능을 '확장' 하는 메서드입니다.
기존에 존재하던 클래스에 내 맘대로 메서드를 추가할 수 있다는 뜻이죠.
이해하기 쉽게 예시를 들어봅시다.
using System;
public void Main()
{
int[] array = new int[10];
}
int 배열을 만들었죠. 근데 전 이 배열을 조금 더 쉽게 다루고 싶습니다.
배열에서 특정 조건을 만족하는 값만 뽑는다거나 말이죠.
아실 분들은 아시겠지만 이런 기능들을 쉽게 제공해주는 Linq라는 기능이 C#에 존재합니다.
특정 조건을 만족하는 값만 뽑는 메서드(Where)는 실제로 배열, List, Dictionary 같은 클래스의 멤버 함수로 존재합니다.
...존재 할까요?
어? 근데 조금 이상하죠.
using System;
public void Main()
{
int[] array = new int[10];
var twoArray = array.Where(value => value == 2); //컴파일 에러
}
array 내부에 Where라는 메서드가 존재하지 않습니다.
근데 using System.Linq를 적어주면 갑자기 없던 Where 메서드가 생기죠.
using System;
using System.Linq;
public void Main()
{
int[] array = new int[10];
var twoArray = array.Where(value => value == 2); //잘됨
}
이게 되는 이유가 Where같은 Linq 메서드를 확장 메서드로 다른 클래스에서 정의했기 때문입니다.
아무튼 어떻게 쓰는지를 알아봅시다.
사용법
확장 메서드를 적을땐 2가지 규칙이 있습니다.
1. 확장 메서드는 정적 클래스 내부의 정적 메서드로써 존재해야 합니다.
어떻게 보면 멤버 함수 같지만 정적 메서드에요.
2. 첫번째 매개변수는 this 키워드와 함께해야합니다.
이게 핵심이에요.
다음과 같이 적으면 이제 당신도 확장 메서드 오우너.
첫번째 매개변수의 자료형에 원래 그런 메서드가 있었던 것 처럼 사용할 수 있습니다.
public static class ExtensionMethods
{
public static int Add(this int a, int b)
{
return a + b;
}
}
public void Main()
{
int a = 3;
Console.WriteLine(a.Add(5)); // 출력 : 8
}
응용
내가 코드 모든 곳(말 그대로)에서 사용할 수 있는 어떠한 메서드를 만들고 싶다고 해봅시다.
그러면 이걸 확장 메서드를 응용해서 만들 수 있어요.
C#의 모든 자료형은 System.Object를 상속합니다.
이 System.Object엔 ToString, GetType같은 익숙한 메서드들이 들어있어요. 그래서 모든 자료형에 ToString이 존재하는거죠.
이걸 이용해서 코드 전역에서 쓸 수 있는 메서드를 만드는겁니다.
예를 들어 비트마스킹을 체크하는 메서드를 만들어봅시다.
Enum 클래스의 HasFlag 같은거 말이죠.
public static class ExtensionMethods
{
public static bool HasFlag(this System.Object obj, int value, int flag)
{
return (value & flag) != 0;
}
}
이런식으로 확장 메서드의 첫번째 매개변수가 System.Object일 경우엔 유사 전역 함수가 돼버리는 겁니다.
C#엔 전역 함수가 존재하지 않기 때문에 이런 방식을 써보면 어떨까 했습니다.
물론 그냥 object를 사용해도 똑같습니다.
근데 조금 불편합니다. this를 붙여줘야 호출할 수 있거든요. 안 붙이면 호출을 못합니다.
public class Um
{
public void DoSomething()
{
this.HasFlag(1,2);
}
}
클래스 내부의 코드는 this를 암시적으로 붙이고 있는거라 this 없이 호출이 가능할 줄 알았는데 아니더군요.
이쪽은 단순히 static 메서드로 만들고 using static을 사용하는게 조금 더 깔끔할 수도 있겠네요.
마치는 말
그냥 갑자기 쓰고 싶어져서 쓴글입니다.
확장 메서드가 참 매력이 많은 기능입니다. C++에도 나왔으면 좋겠어요.
'개발 > C#' 카테고리의 다른 글
[C#] | 한대 때리고 싶은 Exception has been thrown by the target of an invocation. 은 대체 뭐고 어떻게 해결하는걸까 (0) | 2025.02.11 |
---|---|
[C#] | 대체 is not은 뭔데 (2) | 2024.09.26 |
[C#] | Type 비교에서의 'is' 와 'GetType()' (1) | 2024.08.03 |
[C#] | string과 StringBuilder (1) | 2024.04.19 |