我正在將應用程式從 C# 轉換為 PowerShell。如何從 PowerShell 呼叫 LINQ?
[Data.DataTable]$dt = New-Object System.Data.DataTable
[Data.DataColumn]$column = New-Object System.Data.DataColumn "Id", ([int])
$dt.Columns.Add($column)
# add data
[Data.DataRow]$row = $dt.NewRow() #
$row["Id"] = 1
$dt.Rows.Add($row)
$row = $dt.NewRow() #
$row["Id"] = 2
$dt.Rows.Add($row)
# LINQ in C#: int[] results = dt.AsEnumerable().Select(d => d.Field("Id")).ToArray();
[int[]]$results = [Linq.Enumerable]::Select($dt,[Func[int,int]]{ $args[0]})
# Error: Cannot find an overload for "Select" and the argument count: "2"
Write-Host $results
uj5u.com熱心網友回復:
注意:有關在 PowerShell 中使用 LINQ 的限制的一般資訊,請參閱這篇文章。
問題是這System.Linq.Enumerable.Select()是一個泛型方法,PowerShell 無法為所需的型別引數指定型別,至少在 PowerShell 7.2 中是這樣。為了讓它作業,必須使用反射,這很麻煩(見底部)。
但是,您可以使用一個方便的 PowerShell 功能來代替:成員列舉允許您直接在集合(可列舉)上訪問感興趣的屬性,并且 PowerShell 將回傳每個元素的屬性值:
[int[]] $results = $dt.Id # same as: $dt.Rows.Id
$results # print -> array 1, 2
$dt.Id 實際上與以下內容相同: $dt | ForEach-Object { $_.Id }
為了完整起見(這個用例不值得這樣做),這里是基于反射的 LINQ 方法:
# Using reflection, get the open definition of the relevant overload of the
# static [Linq.Enumerable]::Select() method.
# ("Open" means: its generic type parameters aren't yet bound, i.e. aren't
# yet instantiated with concrete types.)
$selectMethod = [Linq.Enumerable].GetMethods().Where({
$_.Name -eq 'Select' -and $_.GetParameters()[-1].ParameterType.Name -eq 'Func`2'
}, 'First')
# Close the method with the types at hand and invoke it via reflection.
[int[]] $results = $selectMethod.MakeGenericMethod([Data.DataRow], [int]).Invoke(
# No instance to operate on - the method is static.
$null,
# The arguments for the method, as an array.
(
[Data.DataRow[]] $dt.Rows,
[Func[Data.DataRow,int]] { $args[0].Id }
)
)
# Output the result.
$results
請注意,上面僅顯示了如何實體化泛型.Select()方法。
為了獲得一個[System.Collections.Generic.IEnumerable`1[System.Data.DataRow]]實體,使用非惰性陣列強制轉換( [System.Data.DataRow[]]) 代替 using System.Linq.Enumerable.AsEnumerable()- 使用后者也需要使用基于反射的方法。
從上面可以明顯看出,從 PowerShell 使用 LINQ 相當麻煩,至少從 v7.2 開始- GitHub 問題 #2226建議在未來引入更好的 LINQ 集成。
對于使用動態(間接)指定的資料型別而不是諸如的資料型別文字的 LINQ 解決方案的更繁瑣的概括,請參閱后續問題的答案。[int]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/405934.html
標籤:
