Итак, я пришел к выводу, что @jdweng прав, разница только в Операторе присваивания сложения +=
. Затем я увидел ваш комментарий и подумал, что вы имеете в виду, например, @jdweng, по сути, сказал, что «ну конечно версия 2 не работает, потому что это одно задание, а не массив элементов. "
.... Итак, я пошел, чтобы доказать, что вы неправы:
Версия 1
PS C:\> $Test1 = @()
PS C:\> (0..2).foreach{ $Test1 += [System.Xml.Linq.XElement]::new("test", "test") }
PS C:\> [System.Xml.Linq.XElement]::new('root',[System.Xml.Linq.XElement]::new("parameters", $Test1)).ToString()
<root>
<parameters>
<test>test</test>
<test>test</test>
<test>test</test>
</parameters>
</root>
PS C:\> $test1.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS C:\> $test1.Count
3
Отлично. Мы знаем, что у нас есть массив и что в нем 3 элемента. Это ожидается, когда мы используем Оператор присваивания сложения +=
. Мы создаем новый объект и добавляем его к существующему $Test1
массиву
Теперь, чтобы доказать свою неправоту. Я настолько уверен, что вместо преобразования в [Array]
я даже буду использовать тот же оператор подвыражения Array , просто чтобы добавить соли в рану:
Версия 2
PS C:\> $Test2 = @()
PS C:\> $Test2 = (0..2).foreach{ [System.Xml.Linq.XElement]::new("test", "test") }
PS C:\> [System.Xml.Linq.XElement]::new('root',[System.Xml.Linq.XElement]::new("parameters", $Test2)).ToString()
<root>
<parameters><test>test</test><test>test</test><test>test</test></parameters>
</root>
А теперь, чтобы доказать свою неправоту:
PS C:\> $test2.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS C:\> $test2.Count
3
Ой ...............
Они выглядят точно так же то же самое. (Потеет)
Они оба относятся к типу array. У них обоих счетчик 3. Вы правы. Это очень актуальный вопрос. Они не должны быть одного и того же типа с 3 элементами и выдавать разные результаты.
Это требует дальнейшего исследования. Что именно происходит?
Версия 1
(0..2).foreach{
$Test1 += [System.Xml.Linq.XElement]::new("test", "test")
}
Если разбить его, как компилятор интерпретирует этот оператор?:
L oop 1:
$Test1 += [System.Xml.Linq.XElement]::new("test", "test")
Результат L oop 1:
$Test1[0] = <test>test</test>
L oop 2:
$Test1 += [System.Xml.Linq.XElement]::new("test", "test")
Результат L oop 2:
$Test1[0] = <test>test</test>
$Test1[1] = <test>test</test>
L oop 3:
$Test1 += [System.Xml.Linq.XElement]::new("test", "test")
Результат L oop 3:
$Test1[0] = <test>test</test>
$Test1[1] = <test>test</test>
$Test1[2] = <test>test</test>
Это ваш ожидаемый результат.
Теперь давайте посмотрим на вторая версия:
Версия 2
$Test2 = @()
$Test2 = (0..2).foreach{ [System.Xml.Linq.XElement]::new("test", "test") }
L oop 1:
[System.Xml.Linq.XElement]::new("test", "test")
Результат L oop 1:
<test>test</test>
L oop 2:
[System.Xml.Linq.XElement]::new("test", "test")
Результат L oop 2:
<test>test</test><test>test</test>
L oop 3:
[System.Xml.Linq.XElement]::new("test", "test")
Результат L oop 3:
<test>test</test><test>test</test><test>test</test>
Final Assignment
$Test2 = <test>test</test><test>test</test><test>test</test>
Вместо добавления дополнительных элементов массива в массив вы предварительно создаете свои элементы, затем присваивая его в массив.
Мы можем увидеть это лучше, если посмотрим на сами элементы:
PS C:\> $test1 |select Name,NodeType,Value,NextNode,PreviousNode,Parent
Name : test
NodeType : Element
Value : test
NextNode : <test>test</test>
PreviousNode :
Parent : <parameters>
<test>test</test>
<test>test</test>
<test>test</test>
</parameters>
Name : test
NodeType : Element
Value : test
NextNode : <test>test</test>
PreviousNode : <test>test</test>
Parent : <parameters>
<test>test</test>
<test>test</test>
<test>test</test>
</parameters>
Name : test
NodeType : Element
Value : test
NextNode :
PreviousNode : <test>test</test>
Parent : <parameters>
<test>test</test>
<test>test</test>
<test>test</test>
</parameters>
Обратите внимание, что, добавляя к массиву, он полностью построил каждый отдельный элемент узел. Каждый «новый» элемент добавлялся индивидуально, и выстраивалось полное «правильное» дерево. а как насчет Test2?
PS C:\> $test2 |select Name,NodeType,Value,NextNode,PreviousNode,Parent
Name : test
NodeType : Element
Value : test
NextNode :
PreviousNode :
Parent :
Name : test
NodeType : Element
Value : test
NextNode :
PreviousNode :
Parent :
Name : test
NodeType : Element
Value : test
NextNode :
PreviousNode :
Parent :
Обратите внимание, что он не построил дерево. Это Flat . Это 3 элемента подряд. Вот почему мы получаем счет 3 . Вот почему это все еще «массив» и «выглядит» так же, но это не так. Нет следующего узла или предыдущего узла, иерархическая структура XML не создается.
Это отсутствие структуры означает, что когда вы пытаетесь построить остальную часть документа XML, $Test2
array возвращается к интерпретации как обычная строка, а не как XML.
TL; DR:
Добавляйте элементы по одному, используя +=
или .Add()
. Это гарантирует, что новый объект, который вы создаете, будет правильно добавлен. Вы создаете 3 новых объектов, напрямую добавляете 3 ссылки на новые объекты.
Vs. Тест 2: вы создаете 3 новых объекта, объединяете выходы объектов (не ссылки), а затем назначаете выходы 3 объектов массиву, дает вам разные результаты .