public static object ToFieldValue(this Java.Lang.Object fieldValue, Type type) { if (fieldValue == null) { return(null); } switch (fieldValue) { case Java.Lang.Boolean @bool: if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { type = type.GenericTypeArguments[0]; } return(Convert.ChangeType((bool)@bool, type)); case Java.Lang.Long @long: if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { type = type.GenericTypeArguments[0]; } return(Convert.ChangeType((long)@long, type)); case Java.Lang.Double @double: if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { type = type.GenericTypeArguments[0]; } return(Convert.ChangeType((double)@double, type)); case Java.Lang.String @string: return(fieldValue.ToString()); case Firebase.Timestamp timestamp: { var time = new Timestamp(timestamp); if (type == typeof(DateTime) || type == typeof(DateTime?)) { return(time.ToDateTime()); } if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?)) { return(time.ToDateTimeOffset()); } return(time); } case Java.Util.Date date: { var time = new Timestamp(date); if (type == typeof(DateTime) || type == typeof(DateTime?)) { return(time.ToDateTime()); } if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?)) { return(time.ToDateTimeOffset()); } return(time); } case JavaList javaList: { IList list; if (type.GetInterfaces().Contains(typeof(IList))) { list = (IList)Activator.CreateInstance(type); } else if (type.IsGenericType) { var listType = typeof(List <>).MakeGenericType(type.GenericTypeArguments[0]); list = (IList)Activator.CreateInstance(listType); } else { list = new List <object>(); } var genericType = typeof(object); if (type.IsGenericType) { genericType = type.GenericTypeArguments[0]; } foreach (var data in javaList) { var value = data; if (value is Java.Lang.Object javaObject) { value = javaObject.ToFieldValue(genericType); } else if (value != null && genericType != typeof(object)) { if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(Nullable <>)) { genericType = genericType.GenericTypeArguments[0]; } value = Convert.ChangeType(value, genericType); } list.Add(value); } return(list); } case Java.Util.AbstractList javaList: { IList list; if (type.GetInterfaces().Contains(typeof(IList))) { list = (IList)Activator.CreateInstance(type); } else if (type.IsGenericType) { var listType = typeof(List <>).MakeGenericType(type.GenericTypeArguments[0]); list = (IList)Activator.CreateInstance(listType); } else { list = new List <object>(); } var genericType = typeof(object); if (type.IsGenericType) { genericType = type.GenericTypeArguments[0]; } var iterator = javaList.Iterator(); while (iterator.HasNext) { object value = iterator.Next(); if (value is Java.Lang.Object javaObject) { value = javaObject.ToFieldValue(genericType); } else if (value != null && genericType != typeof(object)) { if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(Nullable <>)) { genericType = genericType.GenericTypeArguments[0]; } value = Convert.ChangeType(value, genericType); } list.Add(value); } return(list); } case JavaDictionary dictionary: { object @object; if (type == typeof(object)) { @object = new Dictionary <string, object>(); } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { var dictionaryType = typeof(Dictionary <,>).MakeGenericType(type.GenericTypeArguments[0], type.GenericTypeArguments[1]); @object = Activator.CreateInstance(dictionaryType); } else { @object = Activator.CreateInstance(type); } if (@object is IDictionary dict) { var genericType = typeof(object); if (type.IsGenericType) { genericType = type.GenericTypeArguments[1]; } foreach (var key in dictionary.Keys) { var value = dictionary[key]; if (value is Java.Lang.Object javaObject) { value = javaObject.ToFieldValue(genericType); } else if (value != null && genericType != typeof(object)) { if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(Nullable <>)) { genericType = genericType.GenericTypeArguments[0]; } value = Convert.ChangeType(value, genericType); } dict.Add(key.ToString(), value); } } else { var properties = type.GetProperties(); var mappedProperties = properties.Select(p => (Property: p, Attribute: Attribute.GetCustomAttribute(p, typeof(MapToAttribute)) as MapToAttribute)) .Where(t => t.Attribute != null) .ToDictionary(t => t.Attribute.Mapping, t => t.Property); var igonoredProperties = properties.Where(p => Attribute.GetCustomAttribute(p, typeof(IgnoredAttribute)) != null); foreach (var key in dictionary.Keys) { PropertyInfo property; if (mappedProperties.ContainsKey(key.ToString())) { property = mappedProperties[key.ToString()]; } else { property = type.GetProperty(key.ToString()); } if (property != null && !igonoredProperties.Contains(property)) { var value = dictionary[key]; if (value is Java.Lang.Object javaObject) { value = javaObject.ToFieldValue(property.PropertyType); } else if (value != null) { var propertyType = property.PropertyType; if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { propertyType = propertyType.GenericTypeArguments[0]; } value = Convert.ChangeType(value, propertyType); } property.SetValue(@object, value); } } } return(@object); } case Java.Util.AbstractMap map: { object @object; if (type == typeof(object)) { @object = new Dictionary <string, object>(); } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { var dictionaryType = typeof(Dictionary <,>).MakeGenericType(type.GenericTypeArguments[0], type.GenericTypeArguments[1]); @object = Activator.CreateInstance(dictionaryType); } else { @object = Activator.CreateInstance(type); } if (@object is IDictionary dict) { var genericType = typeof(object); if (type.IsGenericType) { genericType = type.GenericTypeArguments[1]; } foreach (var key in map.KeySet()) { object value = map.Get(key.ToString()); if (value is Java.Lang.Object javaObject) { value = javaObject.ToFieldValue(genericType); } else if (value != null && genericType != typeof(object)) { if (genericType.IsGenericType && genericType.GetGenericTypeDefinition() == typeof(Nullable <>)) { genericType = genericType.GenericTypeArguments[0]; } value = Convert.ChangeType(value, genericType); } dict.Add(key.ToString(), value); } } else { var properties = type.GetProperties(); var mappedProperties = properties.Select(p => (Property: p, Attribute: Attribute.GetCustomAttribute(p, typeof(MapToAttribute)) as MapToAttribute)) .Where(t => t.Attribute != null) .ToDictionary(t => t.Attribute.Mapping, t => t.Property); var igonoredProperties = properties.Where(p => Attribute.GetCustomAttribute(p, typeof(IgnoredAttribute)) != null); foreach (var key in map.KeySet()) { PropertyInfo property; if (mappedProperties.ContainsKey(key.ToString())) { property = mappedProperties[key.ToString()]; } else { property = type.GetProperty(key.ToString()); } if (property != null && !igonoredProperties.Contains(property)) { object value = map.Get(key.ToString()); if (value is Java.Lang.Object javaObject) { value = javaObject.ToFieldValue(property.PropertyType); } else if (value != null) { var propertyType = property.PropertyType; if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { propertyType = propertyType.GenericTypeArguments[0]; } value = Convert.ChangeType(value, propertyType); } property.SetValue(@object, value); } } } return(@object); } case Firebase.Firestore.Blob blob: if (type == typeof(byte[])) { return(blob.ToBytes()); } return(new MemoryStream(blob.ToBytes())); case Firebase.Firestore.GeoPoint geoPoint: return(new GeoPoint(geoPoint)); case Firebase.Firestore.DocumentReference documentReference: return(new DocumentReferenceWrapper(documentReference)); default: throw new ArgumentOutOfRangeException($"{fieldValue.GetType().FullName} is not supported"); } }
public static object ToFieldValue(this NSObject fieldValue, Type type) { if (fieldValue == null) { return(null); } switch (fieldValue) { case NSNumber number: if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { type = type.GenericTypeArguments[0]; } if (type == typeof(bool)) { return(number.BoolValue); } if (type == typeof(byte)) { return(number.ByteValue); } if (type == typeof(double)) { return(number.DoubleValue); } if (type == typeof(float)) { return(number.FloatValue); } if (type == typeof(int)) { return(number.Int32Value); } if (type == typeof(long)) { return(number.Int64Value); } if (type == typeof(sbyte)) { return(number.SByteValue); } if (type == typeof(short)) { return(number.Int16Value); } if (type == typeof(uint)) { return(number.UInt32Value); } if (type == typeof(ulong)) { return(number.UInt64Value); } if (type == typeof(ushort)) { return(number.UInt16Value); } return(Convert.ChangeType(number.DoubleValue, type)); case NSString @string: return(@string.ToString()); case Firebase.CloudFirestore.Timestamp timestamp: { var time = new Timestamp(timestamp); if (type == typeof(DateTime) || type == typeof(DateTime?)) { return(time.ToDateTime()); } if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?)) { return(time.ToDateTimeOffset()); } return(time); } case NSDate date: { var time = new Timestamp(date); if (type == typeof(DateTime) || type == typeof(DateTime?)) { return(time.ToDateTime()); } if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?)) { return(time.ToDateTimeOffset()); } return(time); } case NSArray array: { IList list; if (type.GetInterfaces().Contains(typeof(IList))) { list = (IList)Activator.CreateInstance(type); } else if (type.IsGenericType) { var listType = typeof(List <>).MakeGenericType(type.GenericTypeArguments[0]); list = (IList)Activator.CreateInstance(listType); } else { list = new List <object>(); } var genericType = typeof(object); if (type.IsGenericType) { genericType = type.GenericTypeArguments[0]; } for (nuint i = 0; i < array.Count; i++) { list.Add(array.GetItem <NSObject>(i).ToFieldValue(genericType)); } return(list); } case NSDictionary dictionary: { object @object; if (type == typeof(object)) { @object = new Dictionary <string, object>(); } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { var dictionaryType = typeof(Dictionary <,>).MakeGenericType(type.GenericTypeArguments[0], type.GenericTypeArguments[1]); @object = Activator.CreateInstance(dictionaryType); } else { @object = Activator.CreateInstance(type); } if (@object is IDictionary dict) { var genericType = typeof(object); if (type.IsGenericType) { genericType = type.GenericTypeArguments[1]; } foreach (var(key, value) in dictionary) { dict.Add(key.ToString(), value.ToFieldValue(genericType)); } } else { var properties = type.GetProperties(); var mappedProperties = properties.Select(p => (Property: p, Attribute: Attribute.GetCustomAttribute(p, typeof(MapToAttribute)) as MapToAttribute)) .Where(t => t.Attribute != null) .ToDictionary(t => t.Attribute.Mapping, t => t.Property); var igonoredProperties = properties.Where(p => Attribute.GetCustomAttribute(p, typeof(IgnoredAttribute)) != null); foreach (var(key, value) in dictionary) { PropertyInfo property; if (mappedProperties.ContainsKey(key.ToString())) { property = mappedProperties[key.ToString()]; } else { property = type.GetProperty(key.ToString()); } if (property != null && !igonoredProperties.Contains(property)) { property.SetValue(@object, value.ToFieldValue(property.PropertyType)); } } } return(@object); } case NSData data: if (type == typeof(byte[])) { return(data.ToArray()); } return(new MemoryStream(data.ToArray())); case Firebase.CloudFirestore.GeoPoint geoPoint: return(new GeoPoint(geoPoint)); case Firebase.CloudFirestore.DocumentReference documentReference: return(new DocumentReferenceWrapper(documentReference)); case NSNull @null: return(null); default: throw new ArgumentOutOfRangeException($"{fieldValue.GetType().FullName} is not supported"); } }