Почему я могу создавать объекты с помощью [pscustomobject], но не с помощью [System.Management.Automation.PSCustomObject]? - PullRequest
0 голосов
/ 10 апреля 2020

Почему я могу создавать объекты с помощью ускорителя типа [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

Вдохновлен этой темой: https://powershell.org/forums/topic/type-accelerator

1 Ответ

3 голосов
/ 10 апреля 2020

Есть ли какой-нибудь магический конструктор, к которому я не обращаюсь?

Нет, в компиляторе есть волшебный соус c - всякий раз, когда компилятор PowerShell видит выражение приведения, где правая Сторона - это словарь, а у литерала типа есть точное имя pscustomobject, он будет рассматривать словарь или хеш-таблицу (литерал или нет) как упорядоченный словарь и преобразовывать его в PSObject.

Начиная с VisitConvertExpression в 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...