IEnumerableConverterFactoryHelpers
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.Json.Reflection;
namespace System.Text.Json.Serialization
{
internal static class IEnumerableConverterFactoryHelpers
{
internal const string ImmutableConvertersUnreferencedCodeMessage = "System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.";
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.")]
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.")]
public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, Type elementType)
{
Type immutableEnumerableConstructingType = GetImmutableEnumerableConstructingType(type);
if (immutableEnumerableConstructingType != (Type)null) {
MethodInfo[] methods = immutableEnumerableConstructingType.GetMethods();
foreach (MethodInfo methodInfo in methods) {
if (methodInfo.Name == "CreateRange" && methodInfo.GetParameters().Length == 1 && methodInfo.IsGenericMethod && methodInfo.GetGenericArguments().Length == 1)
return methodInfo.MakeGenericMethod(elementType);
}
}
ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(type);
return null;
}
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.")]
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.")]
public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, Type keyType, Type valueType)
{
Type immutableDictionaryConstructingType = GetImmutableDictionaryConstructingType(type);
if (immutableDictionaryConstructingType != (Type)null) {
MethodInfo[] methods = immutableDictionaryConstructingType.GetMethods();
foreach (MethodInfo methodInfo in methods) {
if (methodInfo.Name == "CreateRange" && methodInfo.GetParameters().Length == 1 && methodInfo.IsGenericMethod && methodInfo.GetGenericArguments().Length == 2)
return methodInfo.MakeGenericMethod(keyType, valueType);
}
}
ThrowHelper.ThrowNotSupportedException_SerializationNotSupported(type);
return null;
}
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.")]
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.")]
private static Type GetImmutableEnumerableConstructingType(Type type)
{
string immutableEnumerableConstructingTypeName = type.GetImmutableEnumerableConstructingTypeName();
if (immutableEnumerableConstructingTypeName != null)
return type.Assembly.GetType(immutableEnumerableConstructingTypeName);
return null;
}
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.")]
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("System.Collections.Immutable converters use Reflection to find and create Immutable Collection types, which requires unreferenced code.")]
private static Type GetImmutableDictionaryConstructingType(Type type)
{
string immutableDictionaryConstructingTypeName = type.GetImmutableDictionaryConstructingTypeName();
if (immutableDictionaryConstructingTypeName != null)
return type.Assembly.GetType(immutableDictionaryConstructingTypeName);
return null;
}
public static bool IsNonGenericStackOrQueue(this Type type)
{
if (GetTypeIfExists("System.Collections.Stack, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")?.IsAssignableFrom(type) ?? false)
return true;
if (GetTypeIfExists("System.Collections.Queue, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")?.IsAssignableFrom(type) ?? false)
return true;
return false;
}
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2057:TypeGetType", Justification = "This method exists to allow for 'weak references' to the Stack and Queue types. If those types are used in the app, they will be preserved by the app and Type.GetType will return them. If those types are not used in the app, we don't want to preserve them here.")]
private static Type GetTypeIfExists(string name)
{
return Type.GetType(name, false);
}
}
}