为什么我可以使用 [pscustomobject] 而不是 [System.Management.Automation.PSCustomObject] 创建对象?
How come I can create objects with [pscustomobject] but not [System.Management.Automation.PSCustomObject]?
为什么我可以使用类型加速器 [pscustomobject] 而不是其全名 [System.Management.Automation.PSCustomObject] 创建对象?是否有一些我没有访问的神奇构造函数?
$a = [pscustomobject]@{name='joe'}
$a.gettype().fullname
System.Management.Automation.PSCustomObject
[System.Management.Automation.PSCustomObject]@{name='joe'}
InvalidArgument: Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "System.Management.Automation.PSCustomObject".
或者我可以尝试 [System.Management.Automation.PSObject],但我只得到一个哈希表:
[psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')::get.pscustomobject.fullname
System.Management.Automation.PSObject
[System.Management.Automation.PSObject]@{name='joe'}
Name Value
---- -----
name joe
Is there some magical constructor I'm not accessing?
不,编译器中有神奇的调味料 - 每当 PowerShell 编译器看到右侧是字典且类型字面量具有确切名称 pscustomobject
的强制转换表达式时,它会处理字典或哈希表(无论是否为文字)作为有序字典并将其转换为 PSObject
.
来自VisitConvertExpression
in Compiler.cs:
var typeName = convertExpressionAst.Type.TypeName;
var hashTableAst = convertExpressionAst.Child as HashtableAst;
Expression childExpr = null;
if (hashTableAst != null)
{
var temp = NewTemp(typeof(OrderedDictionary), "orderedDictionary");
if (typeName.FullName.Equals(LanguagePrimitives.OrderedAttribute, StringComparison.OrdinalIgnoreCase))
{
return Expression.Block(
typeof(OrderedDictionary),
new[] { temp },
BuildHashtable(hashTableAst.KeyValuePairs, temp, ordered: true));
}
if (typeName.FullName.Equals("PSCustomObject", StringComparison.OrdinalIgnoreCase))
{
// pure laziness here - we should construct the PSObject directly. Instead, we're relying on the conversion
// to create the PSObject from an OrderedDictionary.
childExpr = Expression.Block(
typeof(OrderedDictionary),
new[] { temp },
BuildHashtable(hashTableAst.KeyValuePairs, temp, ordered: true));
}
}
请注意这也是 [ordered]@{Key='Value'}
导致 OrderedDictionary
的方式
为什么我可以使用类型加速器 [pscustomobject] 而不是其全名 [System.Management.Automation.PSCustomObject] 创建对象?是否有一些我没有访问的神奇构造函数?
$a = [pscustomobject]@{name='joe'}
$a.gettype().fullname
System.Management.Automation.PSCustomObject
[System.Management.Automation.PSCustomObject]@{name='joe'}
InvalidArgument: Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "System.Management.Automation.PSCustomObject".
或者我可以尝试 [System.Management.Automation.PSObject],但我只得到一个哈希表:
[psobject].Assembly.GetType('System.Management.Automation.TypeAccelerators')::get.pscustomobject.fullname
System.Management.Automation.PSObject
[System.Management.Automation.PSObject]@{name='joe'}
Name Value
---- -----
name joe
Is there some magical constructor I'm not accessing?
不,编译器中有神奇的调味料 - 每当 PowerShell 编译器看到右侧是字典且类型字面量具有确切名称 pscustomobject
的强制转换表达式时,它会处理字典或哈希表(无论是否为文字)作为有序字典并将其转换为 PSObject
.
来自VisitConvertExpression
in Compiler.cs:
var typeName = convertExpressionAst.Type.TypeName;
var hashTableAst = convertExpressionAst.Child as HashtableAst;
Expression childExpr = null;
if (hashTableAst != null)
{
var temp = NewTemp(typeof(OrderedDictionary), "orderedDictionary");
if (typeName.FullName.Equals(LanguagePrimitives.OrderedAttribute, StringComparison.OrdinalIgnoreCase))
{
return Expression.Block(
typeof(OrderedDictionary),
new[] { temp },
BuildHashtable(hashTableAst.KeyValuePairs, temp, ordered: true));
}
if (typeName.FullName.Equals("PSCustomObject", StringComparison.OrdinalIgnoreCase))
{
// pure laziness here - we should construct the PSObject directly. Instead, we're relying on the conversion
// to create the PSObject from an OrderedDictionary.
childExpr = Expression.Block(
typeof(OrderedDictionary),
new[] { temp },
BuildHashtable(hashTableAst.KeyValuePairs, temp, ordered: true));
}
}
请注意这也是 [ordered]@{Key='Value'}
导致 OrderedDictionary