I have a class with a large number of properties, example:
class MyStudent {
public string NAME;
public string TUTOR;
public int AGE;
// ... 100+ items
}
The data is read from a fixed width text file:
Matt John 20
JonathonBob 22
The data file is defined in a separate xref file:
NAME 8
TUTOR 8
AGE 2
I want to populate my class from each line of data then add it to a list of this type. This is the method I am using, can it be made more efficient (without changing the input data files)?
Firstly I've read the xref file into a list so I can access the WIDTH field using LINQ.
/* Read File */
List<MyStudent> signal_file = new List<MyStudent>();
while ((_dba_line = _dba_file.ReadLine()) != null)
{
if (!_dba_line.Substring(0, 2).Equals("--")) // Not a comment
{
MyStudent temp_signal = new MyStudent();
int _offset = 0;
int _width = 0;
_width = xref_file.First(item => item.DBU_FIELD == "NAME").WIDTH;
temp_signal.NAME = _dba_line.Substring(_offset, _width).Trim();
_offset += _width;
_width = xref_file.First(item => item.DBU_FIELD == "TUTOR").WIDTH;
temp_signal.TUTOR = _dba_line.Substring(_offset, _width).Trim();
_offset += _width;
// Continue for each property
// ...
// Finally
signal_file.Add(temp_signal);
}
}
I think the key may be that the xref DBU_FIELD always equals the property name in the class and is in the correct order to match the line of data. What I would like to achieve if possible would be closer to:
foreach (XrefObject x in xref_file)
{
_width = x.WIDTH;
temp_signal.(x.DBU_FIELD) = _dba_line.Substring(_offset, _width).Trim();
_offset += _width;
}
// Finally
signal_file.Add(temp_signal);
It's how to use the xref object DBU_FIELD value to access the student object associated property I am unsure of (if possible).
For info in this use the files have been validated prior to use so they are guaranteed to match up correctly.
I am open to create as a struct rather than an object if that makes more sense, there are typically 500 instances each with approx 100 fields of mixed string, int and float.
I am also looking for the best practice way to handle this type of data structure, not just force it to work.
You can use Reflection's GetProperty and SetValue methods
using System.Reflection;
foreach (XrefObject x in xref_file)
{
_width = x.WIDTH;
PropertyInfo prop =
temp_signal.GetType()
.GetProperty(x.DBU_FIELD, BindingFlags.Public | BindingFlags.Instance);
if(prop != null && prop.CanWrite)
{
prop.SetValue(temp_signal, _dba_line.Substring(_offset, _width).Trim(), null);
}
_offset += _width;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With