public FlatFileColumnCollection(FlatFileToLoad toLoad, bool makeHeaderNamesSane, ExplicitTypingCollection explicitlyTypedColumns, string forceHeaders, bool forceHeadersReplacesFirstLineInFile, string ignoreColumns)
 {
     _toLoad = toLoad;
     _makeHeaderNamesSane    = makeHeaderNamesSane;
     _explicitlyTypedColumns = explicitlyTypedColumns;
     _forceHeaders           = forceHeaders;
     _forceHeadersReplacesFirstLineInFile = forceHeadersReplacesFirstLineInFile;
     _ignoreColumns = ignoreColumns;
 }
        public DataTable StronglyTypeTable(DataTable workingTable, ExplicitTypingCollection explicitTypingCollection)
        {
            Dictionary <int, IDecideTypesForStrings> deciders = new Dictionary <int, IDecideTypesForStrings>();
            var factory = new TypeDeciderFactory(_culture);

            if (!string.IsNullOrWhiteSpace(_explicitDateTimeFormat))
            {
                factory.Settings.ExplicitDateFormats = new [] { _explicitDateTimeFormat }
            }
            ;

            DataTable dtCloned = workingTable.Clone();

            bool typeChangeNeeded = false;

            foreach (DataColumn col in workingTable.Columns)
            {
                //if we have already handled it
                if (explicitTypingCollection != null && explicitTypingCollection.ExplicitTypesCSharp.ContainsKey(col.ColumnName))
                {
                    continue;
                }

                //let's make a decision about the data type to use based on the contents
                var computedType = new Guesser();
                computedType.AdjustToCompensateForValues(col);

                //Type based on the contents of the column
                if (computedType.ShouldDowngradeColumnTypeToMatchCurrentEstimate(col))
                {
                    dtCloned.Columns[col.ColumnName].DataType = computedType.Guess.CSharpType;

                    //if we have a type decider to parse this data type
                    if (factory.IsSupported(computedType.Guess.CSharpType))
                    {
                        deciders.Add(col.Ordinal, factory.Create(computedType.Guess.CSharpType)); //record column index and parser
                    }
                    typeChangeNeeded = true;
                }
            }

            if (typeChangeNeeded)
            {
                foreach (DataRow row in workingTable.Rows)
                {
                    dtCloned.Rows.Add(row.ItemArray.Select((v, idx) =>

                                                           deciders.ContainsKey(idx) && v is string s?
                                                           deciders[idx].Parse(s) :
                                                           v).ToArray());
                }

                return(dtCloned);
            }

            return(workingTable);
        }