I’m parsing a CSV file and placing the data in a struct. I’m using the TextFieldParser from this question and it’s working like a charm except that it returns a String[]. Currently I have the ugly process of:
String[] row = parser.ReadFields();
DispatchCall call = new DispatchCall();
if (!int.TryParse(row[0], out call.AccountID)) {
Console.WriteLine("Invalid Row: " + parser.LineNumber);
continue;
}
call.WorkOrder = row[1];
call.Description = row[2];
call.Date = row[3];
call.RequestedDate = row[4];
call.EstStartDate = row[5];
call.CustomerID = row[6];
call.CustomerName = row[7];
call.Caller = row[8];
call.EquipmentID = row[9];
call.Item = row[10];
call.TerritoryDesc = row[11];
call.Technician = row[12];
call.BillCode = row[13];
call.CallType = row[14];
call.Priority = row[15];
call.Status = row[16];
call.Comment = row[17];
call.Street = row[18];
call.City = row[19];
call.State = row[20];
call.Zip = row[21];
call.EquipRemarks = row[22];
call.Contact = row[23];
call.ContactPhone = row[24];
call.Lat = row[25];
call.Lon = row[26];
call.FlagColor = row[27];
call.TextColor = row[28];
call.MarkerName = row[29];
The struct consists of all those fields being Strings except for AccountID being an int. It annoys me that they’re not strongly typed, but let’s over look that for now. Given that parser.ReadFields() returns a String[] is there a more efficient way to fill a struct (possibly converting some values such as row[0] needing to become an int) with the values in the array?
**EDIT:**One restriction I forgot to mention that may impact what kind of solutions will work is that this struct is [Serializable] and will be sent Tcp somewhere else.
Your mileage may vary on whether it is a better solution, but you could use reflection and define an
Attributeclass that you use to mark your struct members with. The attribute would take the array index as an argument. Assigning the value from the right array element would then happen by using reflection.You could define your attribute like this:
This means the attribute can simply be used to associate an
intvalue namedIndexwith a property.Then, you could mark your properties in the struct with that attribute (just some exemplary lines):
The values could then be set with the
Typeobject for your struct type (you can obtain it with thetypeofoperator):This code iterates over all properties of your struct type. For each property, it checks for our custom attribute type defined above. If such an attribute is present, and if the property type is
stringorint, the value is copied from the respective array index.I am checking for
stringandintproperties as that’s the two data types you mentioned in your question. even though you have only one particular index that contains anintvalue now, it’s good for maintainability if this code is prepared to handle any index as a string or an int property.Note that for a greater number of types to handle, I’d suggest not using a chain of
ifandelse if, but rather aDictionary<Type, Func<string, object>>that maps property types to conversion functions.