调用在PowerShell中通用的静态方法 [英] Calling generic static method in PowerShell

查看:128
本文介绍了调用在PowerShell中通用的静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你怎么调用自定义类的通用静态方法在PowerShell中?

How do you call a generic static method of a custom class in Powershell?

由于以下类:

public class Sample
{
    public static string MyMethod<T>( string anArgument )
    {
        return string.Format( "Generic type is {0} with argument {1}", typeof(T), anArgument );
    }
}

这是编译成汇编Classes.dll并加载到PowerShell中是这样的:

And this is compiled into an assembly 'Classes.dll' and loaded into PowerShell like this:

Add-Type -Path "Classes.dll"

什么是调用的MyMethod方法最简单的方法?

What's the easiest way to call the MyMethod method?

推荐答案

您可以调用通用的方法,请参阅后<一个href=\"http://www.leeholmes.com/blog/2007/06/19/invoking-generic-methods-on-non-generic-classes-in-powershell/\"相对=nofollow>在PowerShell中非泛型类中调用泛型方法。

You can call generic methods, refer to the post Invoking Generic Methods on Non-Generic Classes in PowerShell.

这并不简单,你需要使用 MakeGenericMethod 功能。这是pretty简单,如果方法没有覆盖,它得到如果它更难了。

This is not straightforward, you need to use MakeGenericMethod function. It is pretty simple if method doesn't have overrides, it gets harder if it does.

以防万一,从那里复制粘贴code:

Just in case, copy-pasted code from there:

## Invoke-GenericMethod.ps1 
## Invoke a generic method on a non-generic type: 
## 
## Usage: 
## 
##   ## Load the DLL that contains our class
##   [Reflection.Assembly]::LoadFile("c:\temp\GenericClass.dll")
##
##   ## Invoke a generic method on a non-generic instance
##   $nonGenericClass = New-Object NonGenericClass
##   Invoke-GenericMethod $nonGenericClass GenericMethod String "How are you?"
##
##   ## Including one with multiple arguments
##   Invoke-GenericMethod $nonGenericClass GenericMethod String ("How are you?",5)
##
##   ## Ivoke a generic static method on a type
##   Invoke-GenericMethod ([NonGenericClass]) GenericStaticMethod String "How are you?"
## 

param(
    $instance = $(throw "Please provide an instance on which to invoke the generic method"),
    [string] $methodName = $(throw "Please provide a method name to invoke"),
    [string[]] $typeParameters = $(throw "Please specify the type parameters"),
    [object[]] $methodParameters = $(throw "Please specify the method parameters")
    ) 

## Determine if the types in $set1 match the types in $set2, replacing generic
## parameters in $set1 with the types in $genericTypes
function ParameterTypesMatch([type[]] $set1, [type[]] $set2, [type[]] $genericTypes)
{
    $typeReplacementIndex = 0
    $currentTypeIndex = 0

    ## Exit if the set lengths are different
    if($set1.Count -ne $set2.Count)
    {
        return $false
    }

    ## Go through each of the types in the first set
    foreach($type in $set1)
    {
        ## If it is a generic parameter, then replace it with a type from
        ## the $genericTypes list
        if($type.IsGenericParameter)
        {
            $type = $genericTypes[$typeReplacementIndex]
            $typeReplacementIndex++
        }

        ## Check that the current type (i.e.: the original type, or replacement
        ## generic type) matches the type from $set2
        if($type -ne $set2[$currentTypeIndex])
        {
            return $false
        }
        $currentTypeIndex++
    }

    return $true
}

## Convert the type parameters into actual types
[type[]] $typedParameters = $typeParameters

## Determine the type that we will call the generic method on. Initially, assume
## that it is actually a type itself.
$type = $instance

## If it is not, then it is a real object, and we can call its GetType() method
if($instance -isnot "Type")
{
    $type = $instance.GetType()
}

## Search for the method that:
##    - has the same name
##    - is public
##    - is a generic method
##    - has the same parameter types
foreach($method in $type.GetMethods())
{
    # Write-Host $method.Name
    if(($method.Name -eq $methodName) -and
    ($method.IsPublic) -and
    ($method.IsGenericMethod))
    {
        $parameterTypes = @($method.GetParameters() | % { $_.ParameterType })
        $methodParameterTypes = @($methodParameters | % { $_.GetType() })
        if(ParameterTypesMatch $parameterTypes $methodParameterTypes $typedParameters)
        {
            ## Create a closed representation of it
            $newMethod = $method.MakeGenericMethod($typedParameters)

            ## Invoke the method
            $newMethod.Invoke($instance, $methodParameters)

            return
        }
    }
}

## Return an error if we couldn't find that method
throw "Could not find method $methodName"

这篇关于调用在PowerShell中通用的静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆