前段时间我发现这个构造似乎很好地代替了PowerShell中的本地三元条件运算符:
$result = if ( $myBoolExpression ) { 'a' } else { 'b' }
但是我最近发现它的正确性与数据类型有关:对于某些数据类型,它会修改它返回的数据类型!
如果您运行以下测试代码,您将看到它适用于字符串:$ t1是'a',实际上它是一个字符串。 它适用于DateTime对象($ t2)。但是DataTable对象失败了($ t3和$ t4)。它似乎切掉了最外层的容器,并以一种时尚的方式返回下一层。使用$ t3,操作数是空数据表,因此$ t3获得$ null。使用$ t4,操作数是填充数据行的数据表,但$ t4是包含数据行的对象数组。我认为$ t3和$ t4都应该是DataTables。
问题1:为什么这个构造变形某些数据类型而不是其他数据?
问题2:为什么需要GetDataTable()中的最后一行? 我的意思是,如果它是一个简单的“return $ dataTable”而不是“return @(,($ dataTable))”那么它也返回一个对象数组而不是DataTable!那么也许这是同一问题的另一个症状......?
(请注意,我知道还有其他方法可以模仿三元行为 - 尤其是Ternary operator in PowerShell - 但我不喜欢留下无法解释的问题: - )
function DoTest {
$t1 = if ( $true) { 'a' } else { 'b' }
$t1.GetType().Name # prints 'String'
$obj1 = New-Object DateTime
$obj2 = New-Object DateTime
$t2 = if ( $true) { $obj1 } else { $obj2 }
$t2.GetType().Name # prints 'DateTime'
$obj1 = New-Object Data.DataTable
$obj2 = New-Object Data.DataTable
$t3 = if ( $true) { $obj1 } else { $obj2 }
$t3 -eq $null # prints $true!
# $t3.GetType().Name
$obj1 = GetDataTable
"obj1 is " + $obj1.GetType().Name
$obj2 = GetDataTable
$t4 = if ( $true) { $obj1 } else { $obj2 } # Question 1
$t4.GetType().Name # prints 'Object[]'
$t4[0].GetType().Name # prints 'DataRow'
}
DoTest
此处显示补充GetDataTable函数。它仅用作创建非空DataTable的便捷函数:
function GetDataTable {
$dataTable = New-Object Data.DataTable
$Col = New-Object Data.DataColumn
$Col.ColumnName = 'stuff'
$dataTable.Columns.Add($Col )
$row = $dataTable.NewRow()
$row['stuff' ] = 'abc'
$dataTable.Rows.Add($row )
$row = $dataTable.NewRow()
$row['stuff' ] = 'xyz'
$dataTable.Rows.Add($row )
return @(,($dataTable )) # Question 2-- just "return $dataTable" is insufficient
}
答案 0 :(得分:0)
展开数组类型是powershell做的很多事情it can really bite you at the worst of times。
我怀疑$null
的解释是PowerShell's Extended Type System的类似部分。
不幸的是,它有时会变得错综复杂。