Используйте $List[0].VideoHeight
, а не $List.VideoHeight[0]
.
В конце концов, с концептуальной точки зрения вы хотите получить значение .VideoHeight
первого элемента списка ($List[0]
), а не первого элемент значений высоты видео всего списка ($List.VideoHeight
). [1]
Причина, по которой он работает с несколькими элементами в $List
является то, что перечисление члена PowerShell затем возвращает массив из .VideoHeight
значений свойств, где индексация с [0]
работает, как ожидалось.
Причина, по которой это не так работа с ожидаемым элементом single в $List
заключается в том, что тогда возвращается только значение свойства scalar (single) .VideoHeight
и скаляр имеет тип [string]
. Индексирование в одну строку возвращает отдельных символов в строке, что вы и видели.
Простая демонстрация:
PS> ([pscustomobject] @{ VideoHeight = '1080' }).VideoHeight[0]
1 # [char] '1', the first character in string '1080'
против.
PS> ([pscustomobject] @{ VideoHeight = '1080' },
[pscustomobject] @{ VideoHeight = '1081' }).VideoHeight[0]
1080 # [string] '1080', the first element in array '1080', '1081'
Таким образом, есть два фактора, способствующих неожиданному поведению:
Перечисление членов PowerShell применяет тот же лог c, что и при сборе вывода конвейера: Если в коллекции, члены которой перечисляются, случается только один элемент , это значение элемента (свойства) возвращается как есть ; только 2 или более элементов приводят к [object[]]
массиву значений.
- К сожалению, перечисление членов ведет себя так; поведение может быть еще более удивительным, когда значения свойств сами являются массивами: результирующие массивы затем объединяются вместо того, чтобы превращаться в отдельные подмассивы в выходном массиве - см. эту проблему GitHub .
Стандартное поведение типа. NET System.String
([string]
), позволяющее напрямую индексировать символы, составляющие строку (например, "foo"[0]
yielding [char] 'f'
).
Строго говоря, это тот язык, который использует тип, который реализует синтаксический индексатор [...]
, который является формой syntacti c сахар; базовый тип имеет только параметризованное свойство с именем Chars
, которое как C#, так и PowerShell более удобно предоставляют через [...]
.
Однако в случае [string]
это, к сожалению, противоречит унифицированной обработке PowerShell сборов и скаляров, где обычно $scalar[0]
совпадает с $scalar
- см. этот ответ для справочной информации.
[1] Если собирая значения всех $List
.VideoHeight
значений свойств последовательно возвращал массив (почему это не объясняется во втором разделе), эти два оператора будут функционально эквивалентными хотя $List[0].VideoHeight
все еще предпочтительнее для эффективности (не следует создавать промежуточный массив значений свойств), а также во избежание потенциальных конфликтов имен членов, которые по своей природе перечисления членов влечет за собой - см. этот выпуск GitHub .