예제 #1
0
        /// <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));
            }
        }
예제 #3
0
        /// <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));
 }
예제 #5
0
        /// <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);
            }
        }