Example #1
0
        public static void DetectType(string[] values, out Type type, out int sizeMin, out int sizeMax, out bool isAscii, out bool haveEmpty, out List <string> log)
        {
            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }
            log       = new List <string>();
            type      = typeof(string);
            sizeMin   = int.MaxValue;
            sizeMax   = 0;
            isAscii   = true;
            haveEmpty = false;
            // Order matters. First available type will be returned.
            // If all values can be parsed to Int16 then it can be parsed to Int32 and Int64 too.
            var tcs = new TypeCode[]
            {
                TypeCode.Boolean,
                TypeCode.Byte,
                TypeCode.SByte,
                TypeCode.Int16,
                TypeCode.Int32,
                TypeCode.Int64,
                TypeCode.UInt16,
                TypeCode.UInt32,
                TypeCode.UInt64,
                TypeCode.Single,
                TypeCode.Char,
                TypeCode.DateTime,
                TypeCode.Double,
                TypeCode.Decimal,
                TypeCode.String,
                // TypeCode.DBNull,
                // TypeCode.Empty,
                // TypeCode.Object,
            }.ToList();
            // All available types.
            var available = new Dictionary <TypeCode, Type>();

            tcs.ForEach(x => available.Add(x, Type.GetType(nameof(System) + "." + x)));
            //Convert.ChangeType(value, colType);
            for (int i = 0; i < values.Length; i++)
            {
                var value = values[i];
                if (string.IsNullOrEmpty(value))
                {
                    haveEmpty = true;
                    continue;
                }
                // Determine string limits.
                sizeMin  = Math.Min(sizeMin, value.Length);
                sizeMax  = Math.Max(sizeMax, value.Length);
                isAscii &= value.All(x => x < 128);
                // Get available types to test against.
                var availableTypeCodes = available.Keys.ToArray();
                // If only string was left.
                if (availableTypeCodes.Length == 1 && availableTypeCodes[0] == TypeCode.String)
                {
                    return;
                }
                // Test against available types.
                foreach (var tc in availableTypeCodes)
                {
                    switch (tc)
                    {
                    case TypeCode.Boolean:
                        bool resultBool;
                        if (!bool.TryParse(value, out resultBool))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Byte:
                        byte resultByte;
                        if (!byte.TryParse(value, out resultByte))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Char:
                        char resultChar;
                        if (!char.TryParse(value, out resultChar))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.DateTime:
                        DateTime resultDateTime;
                        if (!DateTime.TryParse(value, out resultDateTime))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Decimal:
                        decimal resultDecimal;
                        if (!decimal.TryParse(value, out resultDecimal))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Double:
                        double resultDouble;
                        if (!double.TryParse(value, out resultDouble))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Int16:
                        short resultShort;
                        if (!short.TryParse(value, out resultShort))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Int32:
                        int resultInt;
                        if (!int.TryParse(value, out resultInt))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Int64:
                        long resultLong;
                        if (!long.TryParse(value, out resultLong))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.SByte:
                        sbyte resultSByte;
                        if (!sbyte.TryParse(value, out resultSByte))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Single:
                        float resultFloat;
                        if (!float.TryParse(value, out resultFloat))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.UInt16:
                        ushort resultUShort;
                        if (!ushort.TryParse(value, out resultUShort))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.UInt32:
                        uint resultUInt;
                        if (!uint.TryParse(value, out resultUInt))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.UInt64:
                        ulong resultULong;
                        if (!ulong.TryParse(value, out resultULong))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            type = available.FirstOrDefault().Value;
        }