/// <summary> /// Deserializes <paramref name="CsvText"/> /// in Array of <typeparamref name="T"/> /// </summary> /// <param name="CsvText">Csv File Text</param> /// <param name="UseFirstRowAsHeaders"> /// When true, the First row of the CSV File will be used as column headers. /// When false, the Column Index defined in <see cref="CsvColumnAttribute"/> will be used. /// </param> /// <returns>Array of <typeparamref name="T"/> with values from CSV File</returns> private IEnumerable<T> DeSerializeText(string CsvText, bool UseFirstRowAsHeaders) { if (!UseFirstRowAsHeaders && ColumnSchema.Count(e => e.ColumnNumber == -1) > 0) throw new InvalidOperationException("Column Number not set"); if (CsvText == string.Empty) return new T[0]; List<List<string>> Csv = new List<List<string>>(); //Csv File (as string) StringReader fileReader = new StringReader(CsvText, CsvStyle.Aggregate, CsvStyle.LineDelimiter); while (!fileReader.EOF) { Csv.Add(new List<string>()); StringReader lineReader = new StringReader(fileReader.Read(), CsvStyle.Aggregate, CsvStyle.Delimiter); //Add Cell (replace double Aggregate with single) while (!lineReader.EOF) Csv.Last().Add(lineReader.Read()?.Replace( CsvStyle.Aggregate + CsvStyle.Aggregate, CsvStyle.Aggregate)); } if (UseFirstRowAsHeaders) { //Get the Schema for this file ColumnSchema = new List<CsvColumn>(); foreach (PropertyInfo property in Properties) ColumnSchema.Add(new CsvColumn(property, Csv[0], Strict)); } //Serialize into T List<T> list = new List<T>(); //Start at first row if not using first row as headers for (int i = UseFirstRowAsHeaders ? 1 : 0; i < Csv.Count; i++) { list.Add(new T()); //Process all columns that we are not ignoring foreach (CsvColumn column in ColumnSchema.Where(e => e.ColumnNumber != -1)) { if (column.ColumnNumber < Csv[i].Count) { try { column.Property.SetValue(list.Last(), GetValue(column.Property, Csv[i][column.ColumnNumber])); } catch (System.FormatException) { //Throw parsing error exception throw new InvalidOperationException( $"Error Converting Value to desired format on " + $"Line Number {i}, Column '{column.ColumnName}'/" + $"Column No '{column.ColumnNumber}'. " + $"See inner exception for further details", new InvalidOperationException( $"Target Type was {column.Property.PropertyType}. " + $"Value was '{Csv[i][column.ColumnNumber]}'")); } } } } return list.ToArray(); }