/// <summary> /// Returns an <see cref="IConvertible"/> primitive converted from the specified array <paramref name="value"/> of bytes. /// </summary> /// <typeparam name="T">The type of the expected return <paramref name="value"/> after conversion.</typeparam> /// <param name="value">The value to convert into an <see cref="IConvertible"/>.</param> /// <returns>An <see cref="IConvertible"/> primitive formed by n-bytes beginning at 0.</returns> /// <exception cref="System.ArgumentNullException"> /// <paramref name="value"/> is null. /// </exception> /// <exception cref="TypeArgumentException"> /// <typeparamref name="T"/> is outside the range of allowed types.<br/> /// Allowed types are: <see cref="Boolean"/>, <see cref="Char"/>, <see cref="double"/>, <see cref="Int16"/>, <see cref="Int32"/>, <see cref="ushort"/>, <see cref="UInt32"/> and <see cref="UInt64"/>. /// </exception> public static T FromBytes <T>(byte[] value) where T : struct, IConvertible { Validator.ThrowIfNull(value, nameof(value)); if (BitConverter.IsLittleEndian) { Array.Reverse(value); } TypeCode code = TypeCodeConverter.FromType(typeof(T)); object result; switch (code) { case TypeCode.Boolean: result = BitConverter.ToBoolean(value, 0); break; case TypeCode.Char: result = BitConverter.ToChar(value, 0); break; case TypeCode.Double: result = BitConverter.ToDouble(value, 0); break; case TypeCode.Int16: result = BitConverter.ToInt16(value, 0); break; case TypeCode.Int32: result = BitConverter.ToInt32(value, 0); break; case TypeCode.Int64: result = BitConverter.ToInt64(value, 0); break; case TypeCode.Single: result = BitConverter.ToSingle(value, 0); break; case TypeCode.UInt16: result = BitConverter.ToUInt16(value, 0); break; case TypeCode.UInt32: result = BitConverter.ToUInt32(value, 0); break; case TypeCode.UInt64: result = BitConverter.ToUInt64(value, 0); break; default: throw new TypeArgumentException("T", string.Format(CultureInfo.InvariantCulture, "T appears to be of an invalid type. Expected type is one of the following: Boolean, Char, Double, Int16, Int32, Int64, UInt16, UInt32 or UInt64. Actually type was {0}.", code)); } return((T)result); }
/// <summary> /// Validates if the specified <typeparamref name="T"/> is within the allowed range of numeric operands. /// </summary> /// <typeparam name="T">The type of the value for an operand operation.</typeparam> /// <exception cref="System.ArgumentOutOfRangeException"> /// <typeparamref name="T"/> is outside the range of allowed types.<br/> /// Allowed types are: <see cref="Byte"/>, <see cref="Decimal"/>, <see cref="Double"/>, <see cref="Int16"/>, <see cref="Int32"/>, <see cref="Int64"/>, <see cref="SByte"/>, <see cref="Single"/>, <see cref="UInt16"/>, <see cref="UInt32"/> or <see cref="UInt64"/>. /// </exception> public static void ValidAsNumericOperand <T>() where T : struct, IComparable <T>, IEquatable <T>, IConvertible { Type valueType = typeof(T); TypeCode valueCode = TypeCodeConverter.FromType(valueType); switch (valueCode) { case TypeCode.Byte: case TypeCode.Decimal: case TypeCode.Double: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.SByte: case TypeCode.Single: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: break; default: throw new TypeArgumentOutOfRangeException("T", string.Format(CultureInfo.InvariantCulture, "T appears to contain an invalid type. Expected type is numeric and must be one of the following: Byte, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32 or UInt64. Actually type was {0}.", valueType.Name)); } }
/// <summary> /// Parses the encapsulated instance of the specified <paramref name="wrapper"/> for a human-readable string value. /// </summary> /// <typeparam name="T">The type of the encapsulated instance of <paramref name="wrapper"/>.</typeparam> /// <param name="wrapper">The wrapper object to parse the instance.</param> /// <returns>A human-readable <see cref="string"/> representation of the wrapped instance in the <see cref="Wrapper{T}"/> object.</returns> /// <exception cref="System.ArgumentNullException"> /// <paramref name="wrapper"/> is null. /// </exception> public static string ParseInstance <T>(IWrapper <T> wrapper) { if (wrapper == null) { throw new ArgumentNullException(nameof(wrapper)); } switch (TypeCodeConverter.FromType(wrapper.InstanceType)) { case TypeCode.Boolean: return(wrapper.Instance.ToString().ToLowerInvariant()); case TypeCode.Byte: case TypeCode.Decimal: 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.Double: return(wrapper.InstanceAs <IConvertible>().ToString(CultureInfo.InvariantCulture)); case TypeCode.DateTime: return(wrapper.InstanceAs <DateTime>().ToString("O", CultureInfo.InvariantCulture)); case TypeCode.String: return(wrapper.Instance.ToString()); default: if (TypeUtility.IsKeyValuePair(wrapper.InstanceType)) { PropertyInfo keyProperty = wrapper.InstanceType.GetProperty("Key"); PropertyInfo valueProperty = wrapper.InstanceType.GetProperty("Value"); object keyValue = keyProperty.GetValue(wrapper.Instance, null) ?? "null"; object valueValue = valueProperty.GetValue(wrapper.Instance, null) ?? "null"; return(string.Format(CultureInfo.InvariantCulture, "[{0},{1}]", keyValue, valueValue)); } if (TypeUtility.IsComparer(wrapper.InstanceType) || TypeUtility.IsEqualityComparer(wrapper.InstanceType)) { return(StringConverter.FromType(wrapper.InstanceType)); } switch (wrapper.InstanceType.Name.ToUpperInvariant()) { case "BYTE[]": return(Convert.ToBase64String(wrapper.InstanceAs <byte[]>())); case "GUID": return(wrapper.InstanceAs <Guid>(CultureInfo.InvariantCulture).ToString("D")); case "RUNTIMETYPE": return(StringConverter.FromType(wrapper.InstanceAs <Type>())); case "URI": return(wrapper.InstanceAs <Uri>().OriginalString); default: return(wrapper.Instance.ToString()); } } }
/// <summary> /// Gets the underlying type code of the specified <paramref name="type"/>. /// </summary> /// <param name="type">The type whose underlying <see cref="TypeCode"/> to get.</param> /// <returns>The code of the underlying type, or Empty if <paramref name="type"/> is null.</returns> public static TypeCode AsCode(this Type type) { return(TypeCodeConverter.FromType(type)); }
/// <summary> /// Computes a suitable hash code from the specified sequence of <paramref name="convertibles"/>. /// </summary> /// <param name="convertibles">A sequence of structs implementing the <see cref="IConvertible"/> interface.</param> /// <returns>A 64-bit signed integer that is the hash code of <paramref name="convertibles"/>.</returns> /// <exception cref="System.ArgumentNullException"> /// <paramref name="convertibles"/> is null. /// </exception> public static long GetHashCode64 <T>(IEnumerable <T> convertibles) where T : IConvertible { if (convertibles == null) { throw new ArgumentNullException(nameof(convertibles)); } TypeCode code = TypeCodeConverter.FromType(typeof(T)); unchecked { bool skipFnvPrimeMultiplication = false; long hash = FnvOffset; foreach (T convertible in convertibles) { switch (code) { case TypeCode.Boolean: hash ^= convertible.ToByte(CultureInfo.InvariantCulture); break; case TypeCode.Char: hash ^= convertible.ToChar(CultureInfo.InvariantCulture); break; case TypeCode.DateTime: hash ^= unchecked ((long)convertible.ToDateTime(CultureInfo.InvariantCulture).Ticks); break; case TypeCode.Decimal: hash ^= unchecked ((long)convertible.ToDecimal(CultureInfo.InvariantCulture)); break; case TypeCode.Double: hash ^= unchecked ((long)convertible.ToDouble(CultureInfo.InvariantCulture)); break; case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: hash ^= convertible.ToInt32(CultureInfo.InvariantCulture); break; case TypeCode.Int64: hash ^= unchecked ((long)convertible.ToInt64(CultureInfo.InvariantCulture)); break; case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: hash ^= unchecked ((long)convertible.ToUInt32(CultureInfo.InvariantCulture)); break; case TypeCode.UInt64: hash ^= unchecked ((long)convertible.ToUInt64(CultureInfo.InvariantCulture)); break; case TypeCode.Single: hash ^= unchecked ((long)convertible.ToSingle(CultureInfo.InvariantCulture)); break; case TypeCode.String: string value = convertible as string; if (value == null) { hash ^= HashCodeForNullValue; } else { for (int i = 0; i < value.Length; i++) { hash ^= value[i]; hash *= FnvPrime; skipFnvPrimeMultiplication = true; } } break; } if (!skipFnvPrimeMultiplication) { hash *= FnvPrime; } } return(hash); } }