ReflectionArrayBuilder
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
namespace System.ClientModel.Primitives
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("This class uses reflection. Pass in a generated ModelReaderWriterContext to be AOT compatible.")]
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("This class uses reflection. Pass in a generated ModelReaderWriterContext to be AOT compatible.")]
internal class ReflectionArrayBuilder : ModelReaderWriterTypeBuilder
{
private Type _arrayType;
private Type _builderType;
protected override Type BuilderType => _builderType;
protected override Type ItemType => BuilderType.GenericTypeArguments[0];
public ReflectionArrayBuilder(Type arrayType)
{
_arrayType = arrayType;
_builderType = GetMultiDimensionalList(_arrayType.GetElementType(), _arrayType.GetArrayRank());
}
private static Type GetMultiDimensionalList(Type type, int rank)
{
if (rank == 0)
return type;
return GetMultiDimensionalList(typeof(List<>).MakeGenericType(type), rank - 1);
}
protected override object CreateInstance()
{
return Activator.CreateInstance(BuilderType);
}
protected override void AddItem(object collection, [System.Runtime.CompilerServices.Nullable(2)] object item)
{
BuilderType.GetMethod("Add").Invoke(collection, new object[1] {
item
});
}
protected override object ConvertCollectionBuilder(object builder)
{
if (_arrayType.GetArrayRank() == 1)
return BuilderType.GetMethod("ToArray").Invoke(builder, null);
List<int> list = new List<int>();
object obj = builder;
while (true) {
IList list2 = obj as IList;
if (list2 == null)
break;
list.Add(list2.Count);
obj = ((list2.Count > 0) ? list2[0] : null);
}
Array array = Array.CreateInstance(_arrayType.GetElementType(), list.ToArray());
FillArray(builder, array, Array.Empty<int>());
return array;
}
private static void FillArray(object obj, Array array, int[] indices)
{
IList list = obj as IList;
if (list != null) {
for (int i = 0; i < list.Count; i++) {
int[] indices2 = indices.Append(i).ToArray();
FillArray(list[i], array, indices2);
}
} else
array.SetValue(obj, indices);
}
}
}