Sometime ago I found that this construct seemed to work nicely in lieu of a native ternary conditional operator in PowerShell:
$result = if ( $myBoolExpression ) { 'a' } else { 'b' }
But I recently found that its correctness is datatype-dependent: for certain data types, it will modify the data type it returns!
If you run the following test code, you will see that it works fine for strings: $t1 is 'a' and it is, in fact, a string. And it works fine for DateTime objects ($t2). But it fails for DataTable objects ($t3 and $t4). It seems to slice off the outermost container and return the next layer, after a fashion. With $t3, the operands are empty data tables so $t3 is getting a $null. With $t4, the operands are data tables populated with datarows, but $t4 is an object array containing datarows. Both $t3 and $t4 should have been DataTables, I would have thought.
Question 1: why does this construct morph certain data types but not others?
Question 2: why is the last line in GetDataTable() required? By which, I mean, if it was instead a simple "return $dataTable" instead of "return @(,($dataTable ))" then it also returns an object array instead of a DataTable! So perhaps this is another symptom of the same issue...?
(Note that I am aware there are other ways to emulate ternary behavior--notably Ternary operator in PowerShell--but I don't like leaving unexplained issues around :-)
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
The supplement GetDataTable function is shown here. It is only used as a convenience function to create a non-empty 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
}