PowerShell 제네릭 메서드 호출하기

PowerShell 제네릭 메서드 호출하기

제네릭 타입은 어떤 타입을 쓸지 정해놓고 나중에 구체적인 타입을 채워 넣는 매개변수화된 타입 정의예요. 이렇게 하면 컴파일러와 CLR이 효율적으로 처리해 주는 재사용 가능하고 타입이 안전한 코드를 만들 수 있어요.

출처: Microsoft Learn — about_Calling_Generic_Methods

본문

짧은 설명

제네릭 타입은 List<T>처럼 콘크리트 타입 인수로 인스턴스화하는 매개변수화된 타입 정의예요. 덕분에 재사용 가능하고 타입이 안전한 코드를 만들 수 있고, 컴파일러와 CLR이 그 코드를 효율적으로 처리해 줘요.

자세한 설명

제네릭을 쓰면 메서드, 클래스, 구조체, 인터페이스를 그 대상으로 삼는 정확한 데이터 타입에 맞게 조정할 수 있어요. 예를 들어 키와 값을 어떤 타입으로든 허용하는 System.Collections.Hashtable 클래스 대신에, System.Collections.Generic.Dictionary 제네릭 클래스를 쓰고 키와 값에 허용할 타입을 지정할 수 있어요. 제네릭은 코드 재사용성과 타입 안전성을 높여 줘요.

일부 제네릭 메서드는 PowerShell이 전달된 인수에서 제네릭 인수를 스스로 추론할 수 있어요. 하지만 메서드에 제네릭 오버로드와 비제네릭 오버로드가 섞여 있거나, 제네릭 메서드에 정식 매개변수가 없으면 메서드 결정이 복잡해질 수 있어요. 명시적인 제네릭 메서드 인수 없이 PowerShell이 올바른 메서드를 찾지 못할 수도 있어요.

예를 들어 [array]::Empty[T]()를 봐요. .NET의 Array 클래스에는 정식 매개변수를 받지 않는 정적 제네릭 메서드인 Empty[T]()가 있어요.

PowerShell 7.3 이전에는 올바른 메서드 결정을 보장하려고 .NET 리플렉션을 이용하는 복잡한 꼼수를 써야 했어요. 예시는 Lee Holmes의 블로그 글 Invoking generic methods on non-generic classes in PowerShell에서 볼 수 있어요.

PowerShell 7.3부터는 제네릭 메서드의 타입을 직접 지정할 수 있어요.

구문

제네릭 메서드는 두 개의 매개변수 목록을 가진 메서드예요. 하나는 제네릭 타입 목록이고, 다른 하나는 메서드 인수 목록이에요.

다음 예시는 제네릭 메서드에 접근하는 새 PowerShell 구문을 보여 줘요.

# static generic methods
[type_name]::MethodName[generic_type_arguments](method_arguments)

# instance generic methods
$object.MethodName[generic_type_arguments](method_arguments)

generic_type_arguments는 단일 타입이거나 [string, int]처럼 쉼표로 구분된 타입 목록이 될 수 있어요. 다른 제네릭 타입도 포함할 수 있는데, 예를 들어 $obj.MethodName[string, System.Collections.Generic.Dictionary[string, int]]()처럼 쓸 수 있어요.

method_arguments는 0개 이상의 항목이 될 수 있어요.

자세한 내용은 .NET의 제네릭 문서를 참고해요.

예시

이 예시에서는 정수 목록을 만들고, System.Linq.Enumerable 클래스를 써서 값을 열거한 다음 새 값으로 변환해요.

변수 $list는 정수만 담을 수 있는 제네릭 List[T] 객체예요. List[T]는 생성할 때 멤버의 타입을 지정할 수 있는 제네릭 클래스예요. [System.Linq.Enumerable]::Select[T1,T2](T1,T2)는 제네릭 타입 매개변수 두 개와 정식 값 매개변수 두 개가 필요한 제네릭 메서드예요.

[System.Collections.Generic.List[int]]$list = @( 1, 2, 3, 4, 5 )
$result = [System.Linq.Enumerable]::Select[int, float](
 $list,
 [Func[int, float]]{
   param($Item)
   [Math]::Pow($Item, 3)
 }
)
$result

출력은 각 값을 3제곱한 결과를 보여 줘요.

1
8
27
64
125

더 알아보기