public static TypeInfo BuildICollectionInterfaceType(DynamicFormatterAssembly assembly, Type type, Type elementType) { TypeBuilder typeBuilder = assembly.DefineCollectionFormatterType(type, elementType); MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type); MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type); MethodBuilder sizeMethod = TypeBuildHelper.DefineSizeMethod(typeBuilder, type); if (type.IsGenericType == false) { DEBUG.Assert(type == typeof(IEnumerable) || type == typeof(IList) || type == typeof(ICollection)); //itemType is Object, Array2 if (type == typeof(IList)) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIList), BindingFlags.Public | BindingFlags.Static)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(typeof(object))); TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeIEnumerable), BindingFlags.Public | BindingFlags.Static)); } else { Type genericTypeDefine = type.GetGenericTypeDefinition(); DEBUG.Assert(genericTypeDefine == typeof(IEnumerable <>) || genericTypeDefine == typeof(IList <>) || genericTypeDefine == typeof(ICollection <>) || genericTypeDefine == typeof(ISet <>) || genericTypeDefine == typeof(IReadOnlyList <>) || genericTypeDefine == typeof(IReadOnlyCollection <>)); if (Array1FormatterHelper.IsArray1Type(elementType)) { //Array1 TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SerializeIEnumerable), new Type[] { typeof(BssomWriter).MakeByRefType(), typeof(BssomSerializeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(elementType) })); if (genericTypeDefine == typeof(ISet <>)) { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array1FormatterHelper).GetMethod(Array1FormatterHelper.DeserializeSetPrefix + elementType.Name, BindingFlags.Public | BindingFlags.Static)); } else { Type listFormatterType = Array1ResolverGetFormatterHelper.GetListFormatterType(elementType); FieldInfo field = listFormatterType.GetField(nameof(DateTimeListFormatter.Instance), BindingFlags.Static | BindingFlags.Public); MethodInfo method = listFormatterType.GetMethod(nameof(DateTimeListFormatter.Deserialize)); TypeBuildHelper.CallOneStaticFieldMethodInDeserialize(deserializeMethod, field, method); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SizeIEnumerable), new Type[] { typeof(BssomSizeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(elementType) })); } else { if (genericTypeDefine == typeof(IList <>) || genericTypeDefine == typeof(IReadOnlyList <>)) { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenerIList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } else { TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } if (genericTypeDefine == typeof(ISet <>)) { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeSet), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } else { TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType)); } } return(typeBuilder.CreateTypeInfo()); }