/// <summary> /// Performs a default comparison of two objects of the same type and returns a value indicating whether one object is less than, equal to, or greater than the other. /// </summary> /// <typeparam name="T">The type of the objects to compare.</typeparam> /// <param name="x">The first object to compare.</param> /// <param name="y">The second object to compare.</param> /// <param name="typeSelector">The function delegate that is used to select the <see cref="Type"/> of the objects to compare.</param> /// <param name="valueSelector">The function delegate that is used to select the value of <paramref name="x"/> and <paramref name="y"/>.</param> /// <returns>A signed integer that indicates the relative values of <paramref name="x"/> and <paramref name="y"/>.</returns> public static int Default <T>(T x, T y, Func <T, Type> typeSelector, Func <T, object> valueSelector) { Validator.ThrowIfNull(typeSelector, nameof(typeSelector)); Validator.ThrowIfNull(valueSelector, nameof(valueSelector)); object xValue = valueSelector(x); object yValue = valueSelector(y); TypeCode code = TypeCodeConverter.FromType(typeSelector(x)); switch (code) { case TypeCode.Boolean: return(Comparer <bool> .Default.Compare(Converter.FromObject <bool>(xValue), Converter.FromObject <bool>(yValue))); case TypeCode.Byte: return(Comparer <byte> .Default.Compare(Converter.FromObject <byte>(xValue), Converter.FromObject <byte>(yValue))); case TypeCode.Char: return(Comparer <char> .Default.Compare(Converter.FromObject <char>(xValue), Converter.FromObject <char>(yValue))); case TypeCode.DateTime: return(Comparer <DateTime> .Default.Compare(Converter.FromObject <DateTime>(xValue), Converter.FromObject <DateTime>(yValue))); case TypeCode.Decimal: return(Comparer <decimal> .Default.Compare(Converter.FromObject <decimal>(xValue), Converter.FromObject <decimal>(yValue))); case TypeCode.Double: return(Comparer <double> .Default.Compare(Converter.FromObject <double>(xValue), Converter.FromObject <double>(yValue))); case TypeCode.Int16: return(Comparer <short> .Default.Compare(Converter.FromObject <short>(xValue), Converter.FromObject <short>(yValue))); case TypeCode.Int32: return(Comparer <int> .Default.Compare(Converter.FromObject <int>(xValue), Converter.FromObject <int>(yValue))); case TypeCode.Int64: return(Comparer <long> .Default.Compare(Converter.FromObject <long>(xValue), Converter.FromObject <long>(yValue))); case TypeCode.SByte: return(Comparer <sbyte> .Default.Compare(Converter.FromObject <sbyte>(xValue), Converter.FromObject <sbyte>(yValue))); case TypeCode.Single: return(Comparer <float> .Default.Compare(Converter.FromObject <float>(xValue), Converter.FromObject <float>(yValue))); case TypeCode.String: return(Comparer <string> .Default.Compare(Converter.FromObject <string>(xValue), Converter.FromObject <string>(yValue))); case TypeCode.UInt16: return(Comparer <ushort> .Default.Compare(Converter.FromObject <ushort>(xValue), Converter.FromObject <ushort>(yValue))); case TypeCode.UInt32: return(Comparer <uint> .Default.Compare(Converter.FromObject <uint>(xValue), Converter.FromObject <uint>(yValue))); case TypeCode.UInt64: return(Comparer <ulong> .Default.Compare(Converter.FromObject <ulong>(xValue), Converter.FromObject <ulong>(yValue))); default: return(Comparer <object> .Default.Compare(Converter.FromObject <object>(xValue), Converter.FromObject <object>(yValue))); } }
/// <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()); }; }