in rd-net/RdFramework.Reflection/ReflectionRdActivator.cs [353:415]
private object? ActivateGenericMember(string memberName, TypeInfo memberType)
{
var implementingType = ReflectionSerializerVerifier.GetImplementingType(memberType);
var genericDefinition = implementingType.GetGenericTypeDefinition();
var genericArguments = implementingType.GetTypeInfo().GetGenericArguments();
var argument = genericArguments[0];
var serializerPair = GetProperSerializer(argument);
if (genericDefinition == typeof(RdProperty<>) ||
genericDefinition == typeof(RdSignal<>) ||
genericDefinition == typeof(RdSet<>))
{
var instance = Activator.CreateInstance(implementingType, serializerPair.Reader, serializerPair.Writer);
if (IsMonomorphic(argument))
ReflectionUtil.InvokeStaticGeneric(typeof(ReflectionRdActivator), nameof(SetOptimizeNested1), argument, instance);
return instance;
}
if (genericDefinition == typeof(RdList<>))
{
var instance = Activator.CreateInstance(implementingType, serializerPair.Reader, serializerPair.Writer, 1L /*nextVersion*/);
if (IsMonomorphic(argument))
ReflectionUtil.InvokeStaticGeneric(typeof(ReflectionRdActivator), nameof(SetOptimizeNested1), argument, instance);
return instance;
}
if (genericArguments.Length == 2)
{
var argument2 = genericArguments[1];
var serializerPair2 = GetProperSerializer(argument2);
var instance = Activator.CreateInstance(implementingType, serializerPair.Reader, serializerPair.Writer, serializerPair2.Reader, serializerPair2.Writer);
if (IsMonomorphic(argument2))
ReflectionUtil.InvokeStaticGeneric2(typeof(ReflectionRdActivator), nameof(SetOptimizeNested2), argument, argument2, instance);
return instance;
}
if (genericDefinition == typeof(Nullable<>))
{
// already initialized to null
return null;
}
// hack for UProperty & USignal
if (genericArguments.Length == 1 && typeof(IRdBindable).IsAssignableFrom(implementingType) && implementingType.IsClass)
{
foreach (var ctor in implementingType.GetTypeInfo().GetConstructors(BindingFlags.Public | BindingFlags.Instance))
{
var parameters = ctor.GetParameters();
if (parameters.Length == 3 && parameters[0].Name == "id")
{
return Activator.CreateInstance(implementingType, memberName, serializerPair.Reader, serializerPair.Writer);
}
}
}
throw new Assertion.AssertionException($"Unable to activate generic type: {memberType}");
static bool IsMonomorphic(Type type)
{
return type.IsValueType || (!typeof(IRdBindable).IsAssignableFrom(type) && type.IsSealed);
}
}