2015-09-16 39 views
1

有时前,我发现,这个结构似乎代替本土的三元条件运算符很好地工作在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()中的最后一行是必需的?我的意思是,如果它是一个简单的“返回$ 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 
} 

回答

相关问题