/// <summary> /// Resolves the formatter that will be used for <see cref="Formatter{TFormat}.Serialize(object)"/> operations. /// </summary> /// <param name="sourceType">The type of the object to resolve a formatter.</param> /// <value>The delegate that converts an object.</value> public Action <TWriter, TWriterOptions, object> ParseWriterFormatter(Type sourceType) { Action <TWriter, TWriterOptions, object> writerDelegate = null; if (WriterFormatters.Count > 0 && WriterFormatters.TryGetValue(sourceType, keys => keys.FirstOrDefault(type => TypeUtility.ContainsType(sourceType, type)), out writerDelegate)) { } else { var interfaces = sourceType.GetInterfaces(); foreach (var @interface in interfaces) { if (WriterFormatters.TryGetValue(@interface, out writerDelegate)) { break; } } } return(WriterFormatter ?? writerDelegate); }
/// <summary> /// Resolves the formatter that will be used for <see cref="Formatter{TFormat}.Deserialize{T}"/> operations. /// </summary> /// <param name="sourceType">The type of the object to resolve a formatter.</param> /// <value>The delegate that converts an object.</value> public Func <TReader, TReaderOptions, Type, object> ParseReaderFormatter(Type sourceType) { Func <TReader, TReaderOptions, Type, object> readerDelegate = null; if (ReaderFormatters.Count > 0 && ReaderFormatters.TryGetValue(sourceType, keys => keys.FirstOrDefault(type => TypeUtility.ContainsType(sourceType, type)), out readerDelegate)) { } else { var interfaces = sourceType.GetInterfaces(); foreach (var @interface in interfaces) { if (ReaderFormatters.TryGetValue(@interface, out readerDelegate)) { break; } } } return(ReaderFormatter ?? readerDelegate); }
/// <summary> /// Initializes a new instance of the <see cref="ObjectHierarchyOptions"/> class. /// </summary> public ObjectHierarchyOptions() { MaxDepth = 10; MaxCircularCalls = 2; SkipPropertyType = source => { switch (TypeCodeConverter.FromType(source)) { case TypeCode.Boolean: case TypeCode.Byte: case TypeCode.Decimal: case TypeCode.Double: case TypeCode.Empty: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.SByte: case TypeCode.Single: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.String: return(true); default: if (TypeUtility.IsKeyValuePair(source)) { return(true); } if (TypeUtility.ContainsType(source, typeof(MemberInfo))) { return(true); } return(false); } }; SkipProperty = property => { return(property.PropertyType.GetTypeInfo().IsMarshalByRef || property.PropertyType.GetTypeInfo().IsSubclassOf(typeof(Delegate)) || property.Name.Equals("SyncRoot", StringComparison.Ordinal) || property.Name.Equals("IsReadOnly", StringComparison.Ordinal) || property.Name.Equals("IsFixedSize", StringComparison.Ordinal) || property.Name.Equals("IsSynchronized", StringComparison.Ordinal) || property.Name.Equals("Count", StringComparison.Ordinal) || property.Name.Equals("HResult", StringComparison.Ordinal) || property.Name.Equals("TargetSite", StringComparison.Ordinal)); }; HasCircularReference = ReflectionUtility.HasCircularReference; PropertyIndexParametersResolver = infos => { List <object> resolvedParameters = new List <object>(); for (int i = 0; i < infos.Length; i++) { // because we don't know the values to pass to an indexer we will try to do some assumptions on a "normal" indexer // however; this has it flaws: an indexer does not necessarily have an item on 0, 1, 2 etc., so must handle the possible // TargetInvocationException. // more info? check here: http://blog.nkadesign.com/2006/net-the-limits-of-using-reflection/comment-page-1/#comment-10813 if (TypeUtility.ContainsType(infos[i].ParameterType, typeof(Byte), typeof(Int16), typeof(Int32), typeof(Int64))) // check to see if we have a "normal" indexer { resolvedParameters.Add(0); } } return(resolvedParameters.ToArray()); }; }