public static bool IsSerializable(FieldDefinition field, IReadOnlyDictionary <GenericParameter, TypeReference> arguments) { if (IsSerializableModifier(field)) { MonoSerializableScope scope = new MonoSerializableScope(field, arguments); return(IsFieldTypeSerializable(scope)); } return(false); }
public static bool IsFieldTypeSerializable(MonoSerializableScope scope) { TypeReference fieldType = scope.FieldType; // if it's generic parameter then get its real type if (fieldType.IsGenericParameter) { GenericParameter parameter = (GenericParameter)fieldType; fieldType = scope.Arguments[parameter]; } if (fieldType.IsArray) { ArrayType array = (ArrayType)fieldType; // one dimention array only if (!array.IsVector) { return(false); } // if it's generic parameter then get its real type TypeReference elementType = array.ElementType; if (elementType.IsGenericParameter) { GenericParameter parameter = (GenericParameter)elementType; elementType = scope.Arguments[parameter]; } // array of arrays isn't serializable if (elementType.IsArray) { return(false); } // array of generics isn't serializable if (MonoType.IsSerializableGeneric(elementType)) { return(false); } // check if array element is serializable MonoSerializableScope elementScope = new MonoSerializableScope(scope.DeclaringType, elementType, true, scope.Arguments); return(IsFieldTypeSerializable(elementScope)); } if (MonoType.IsList(fieldType)) { // list is serialized same way as array, so check its argument GenericInstanceType list = (GenericInstanceType)fieldType; TypeReference listElement = list.GenericArguments[0]; // if it's generic parameter then get its real type if (listElement.IsGenericParameter) { GenericParameter parameter = (GenericParameter)listElement; listElement = scope.Arguments[parameter]; } // list of arrays isn't serializable if (listElement.IsArray) { return(false); } // list of buildin generics isn't serializable if (MonoType.IsBuiltinGeneric(listElement)) { return(false); } // check if list element is serializable MonoSerializableScope elementScope = new MonoSerializableScope(scope.DeclaringType, listElement, true, scope.Arguments); return(IsFieldTypeSerializable(elementScope)); } if (fieldType.IsPrimitive) { return(true); } if (MonoType.IsString(fieldType)) { return(true); } if (MonoType.IsEngineStruct(fieldType)) { return(true); } if (MonoType.IsEnginePointer(fieldType)) { return(true); } if (MonoType.IsObject(fieldType)) { return(false); } if (fieldType.IsGenericInstance) { return(MonoType.IsSerializableGeneric(fieldType)); } if (IsRecursive(scope.DeclaringType, fieldType)) { return(scope.IsArrayElement); } TypeDefinition definition = fieldType.Resolve(); if (definition.IsInterface) { return(false); } if (definition.IsAbstract) { return(false); } if (MonoType.IsCompilerGenerated(definition)) { return(false); } if (definition.IsSerializable) { return(true); } if (definition.IsEnum) { return(true); } return(false); }