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; }