在PowerShell中调用静态通用LINQ扩展方法

时间:2017-05-10 03:19:12

标签: linq powershell generics extension-methods

可以使用这个简单的表示法在PowerShell中调用许多LINQ方法:

[int[]] $numbers = 1..10000
[Linq.Enumerable]::Sum($numbers)

在呼叫中包含lambda甚至是一件相对简单的事情:

[Func[int,int]] $delegate = { $n = $args[0]; if ($n % 3) { $n } else { -$n } }
[Linq.Enumerable]::Sum($numbers, $delegate)

但我想知道的是如何从PowerShell调用泛型 LINQ方法:它甚至可能吗? 我发现this SO question似乎表明可以,但我还没有确定如何将该信息应用于LINQ。 (另外,这是旧信息的事实,很有可能在PS版本5中有更简洁的方法来实现它。)

那么如何在PowerShell中正确调用[Linq.Enumerable]::Cast<T>(...)[Linq.Enumerable]::OfType<T>(...)

2017.05.10更新

好的,基于@Mathias评论,让我们坚持使用MakeGenericMethod。在C#中,这个咒语起作用:

var ofTypeForString = typeof(System.Linq.Enumerable).GetMethod("OfType").MakeGenericMethod(typeof(string));
var stuff = new object[] { 1.2, "abc", "def" };
var results = ofTypeForString.Invoke(null, new[] { stuff });

我仍然缺少的是如何将typeof(System.Linq.Enumerable)翻译为PowerShell。我认为其中至少有一个应该可以工作,但它们都返回null:

[System.Type]::GetType("System.Linq.Enumerable")
[System.Type]::GetType("Linq.Enumerable")
[System.Type]::GetType("Enumerable")

我确信我错过了一些简单的东西;建议?

1 个答案:

答案 0 :(得分:2)

是的,当然,PetSerAl和ejohnson的评论都是正确的;我出于某种原因只是精神障碍。因此,对于那些可能感兴趣的人来说,这是完整的解决方案:

$stringType = "".GetType() # set to your target type
$ofTypeForString =
        [Linq.Enumerable].GetMethod("OfType").MakeGenericMethod($stringType)
$stuff = @("12345", 12, "def")
# The last comma below wraps the array arg $stuff within another array
$ofTypeForString.Invoke($null, (,$stuff))