in rd-net/RdFramework.Reflection/BuiltInSerializers.cs [75:147]
public static BuiltInType GetBuiltInType(TypeInfo t)
{
if (HasBuiltInAttribute(t))
return BuiltInType.MarshallerAttribute;
try
{
var writeMethod = t.GetMethod("Write", BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
if (writeMethod != null)
{
return CheckWriteMethod(t, writeMethod);
}
}
catch (AmbiguousMatchException)
{
// More than one Write method exist. We should enumerate members to find appropriate overload.
// not a default branch because of array allocation.
foreach (var member in t.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
if (member is MethodInfo writeMethod && StringComparer.Ordinal.Equals("Write", writeMethod.Name))
{
var type = CheckWriteMethod(t, writeMethod);
if (type != BuiltInType.None)
return type;
}
}
}
var fieldInfo = t.GetField("Write", BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
if (fieldInfo != null)
{
return BuiltInType.StaticFields;
}
return BuiltInType.None;
static BuiltInType CheckWriteMethod(Type ownerType, MethodInfo methodInfo)
{
var genericLength = ownerType.GetGenericArguments().Length;
var parameters = methodInfo.GetParameters();
if (genericLength == 1 || genericLength == 2)
{
// more than one Read is defined for RdMap. We can't query method by name directly and have to allocate array.
var likeReadMethods = ownerType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly);
foreach (var likeReadMethod in likeReadMethods)
{
if (!StringComparer.Ordinal.Equals("Read", likeReadMethod.Name))
continue;
var readParameters = likeReadMethod.GetParameters();
if (readParameters.Length == 2 + genericLength * 2 && readParameters[0].ParameterType == typeof(SerializationCtx))
return genericLength == 1 ? BuiltInType.ProtocolCollectionLike1 : BuiltInType.ProtocolCollectionLike2;
}
}
var likeProtocol = parameters.Length == 2 + (methodInfo.IsStatic ? 1 : 0) &&
parameters[0].ParameterType == typeof(SerializationCtx) &&
parameters[1].ParameterType == typeof(UnsafeWriter);
var likeMethods = parameters.Length == 1 + (methodInfo.IsStatic ? 1 : 0) &&
parameters[0].ParameterType == typeof(UnsafeWriter);
if (methodInfo.IsStatic)
{
if (likeProtocol) return BuiltInType.StaticProtocolMethods;
if (likeMethods) return BuiltInType.StaticMethods;
}
else
{
if (likeProtocol) return BuiltInType.ProtocolMethods;
if (likeMethods) return BuiltInType.Methods;
}
return BuiltInType.None;
}
}