diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs
index 0c08561ba20ced..1418b7342558d8 100644
--- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs
+++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs
@@ -1139,13 +1139,10 @@ private static bool IsWildcard(SpecialMapping mapping)
Type collectionType = memberMapping.TypeDesc!.Type!;
o = ReflectionCreateObject(memberMapping.TypeDesc.Type!);
- if (memberMapping.ChoiceIdentifier != null)
- {
- // https://github.com/dotnet/runtime/issues/1400:
- // To Support ArrayMapping Types Having ChoiceIdentifier
- throw new NotImplementedException("memberMapping.ChoiceIdentifier != null");
- }
-
+ // When this array is the value of a member that carries an [XmlChoiceIdentifier]
+ // (e.g. one of the choice element types is itself an array), the parallel choice
+ // value is recorded by the calling WriteElement against the owning member after
+ // this method returns, so no additional choice handling is needed here.
var arrayMember = new Member(memberMapping);
arrayMember.Collection = new CollectionMember();
arrayMember.ArraySource = arrayMember.Collection.Add;
diff --git a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs
index 1451e7407d8148..35a2d1a01ae9e8 100644
--- a/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs
+++ b/src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.cs
@@ -1927,6 +1927,33 @@ public static void Xml_TypeWithArrayPropertyHavingComplexChoice()
Assert.True(Enumerable.SequenceEqual(value.ManyChoices, actual.ManyChoices));
}
+ [Fact]
+ public static void Xml_TypeWithArrayLikeChoiceElement()
+ {
+ // Exercises an [XmlChoiceIdentifier] member where one of the choice element types is
+ // itself an array, so that element's mapping is an ArrayMapping. Deserializing such a
+ // value drives the reflection-based reader's array-reading path while the owning member
+ // carries a choice identifier.
+ var value = new TypeWithArrayLikeChoiceElement()
+ {
+ ManyChoices = new object[] { "hello", new int[] { 1, 2, 3 } },
+ ChoiceArray = new ArrayLikeChoice[] { ArrayLikeChoice.Word, ArrayLikeChoice.Numbers }
+ };
+
+ var actual = SerializeAndDeserialize(value, WithXmlHeader("\r\n hello\r\n \r\n 1\r\n 2\r\n 3\r\n \r\n"));
+
+ Assert.NotNull(actual);
+ Assert.NotNull(actual.ManyChoices);
+ Assert.Equal(2, actual.ManyChoices.Length);
+ Assert.Equal("hello", actual.ManyChoices[0]);
+ int[] numbers = Assert.IsType(actual.ManyChoices[1]);
+ Assert.Equal(new int[] { 1, 2, 3 }, numbers);
+
+ // The [XmlIgnore] choice array is populated during deserialization to mirror, per item,
+ // which element each value was read from.
+ Assert.Equal(new ArrayLikeChoice[] { ArrayLikeChoice.Word, ArrayLikeChoice.Numbers }, actual.ChoiceArray);
+ }
+
[Fact]
public static void XML_TypeWithTypeNameInXmlTypeAttribute_WithValue()
{
@@ -3272,3 +3299,23 @@ private static string GuessCachedName(string name)
throw new ArgumentException($"Cannot guess cached field name from switch name '{name}'");
}
}
+
+public class TypeWithArrayLikeChoiceElement
+{
+ // One of the choice element types (Numbers) is an array, so its element mapping is an
+ // ArrayMapping. Each item in ManyChoices is matched to an item in ChoiceArray.
+ [XmlChoiceIdentifier("ChoiceArray")]
+ [XmlElement("Word", typeof(string))]
+ [XmlElement("Numbers", typeof(int[]))]
+ public object[] ManyChoices;
+
+ [XmlIgnore]
+ public ArrayLikeChoice[] ChoiceArray;
+}
+
+public enum ArrayLikeChoice
+{
+ None,
+ Word,
+ Numbers
+}