I'm not sure if I'm explaining this correctly, or if the question is clear enough, but here's what I want to do.
I have created an object called index which stores the index of a elements in IList. Here's my ojbect index.
var index = new
{
PhoneReportID = 1,
CSQID = i.NextIndex(),
CallsPresented = i.NextIndex(),
AvgQueueTime = i.NextIndex(),
CallsHandled = i.NextIndex(),
AvgAnswerSpeed = i.NextIndex(),
AvgHandleTime = i.NextIndex(),
CallsAbandoned = i.NextIndex(),
AvgAbandonTime = i.NextIndex(),
AvgCallsAbandoned = i.NextIndex(),
CallsDequeued = i.NextIndex(),
AvgDequeueTime = i.NextIndex(),
CallsHandledByOther = i.NextIndex(),
MaxQueueTime = z.NextIndex(),
MaxHandleTime = z.NextIndex(),
MaxAbandonTime = z.NextIndex(),
MaxCallsAbandoned = z.NextIndex(),
MaxDequeueTime = z.NextIndex(),
};
And Here's my generic method which gets the property from generic type and sets the values based on the element location from index.
private IEnumerable<T> Parse(IList<string[]> rows, object index)
{
Type indexType = index.GetType();
IList<PropertyInfo> indexProperties = indexType.GetProperties();
int k = 0;
var classType = typeof(T);
IList<PropertyInfo> classProperties = classType.GetProperties();
foreach (var property in classProperties)//.Select(x => x.ToString()).Select(y => y.Trim()).ToList())
{
var propGetter = property.GetGetMethod();
var propSetter = indexType.GetProperty(property.Name).GetSetMethod();
var valueToSet = rows[int.TryParse(index[indexType.GetProperty(property.Name)],out k)];
}
throw new Exception();
}
There are many reasons why I'm doing this, but one of the main reasons I'm doing this is to learn Reflection in c#.
So, the rows is a list that is obtained from reading a file with certain delimeter. Since each value in the list corresponds to certain properties of a class, I created an object called index with the names same as the property name of the class and assigned it the location of the value in the IList. Now, I want to retrieve the value in the row using property name of the index which returns the location where the property name of the class is the same as the property name of the object index. The way I have done above is not correct for retrieving the value, but I wrote it in order for clarity of what I intend to achieve. Hopefully, I'm clear enough for someone to answer the question.
private IEnumerable<T> Deserialize<T>(IList<string[]> rows, object index)
where T : new()
{
Type indexType = index.GetType();
IList<PropertyInfo> indexProperties = indexType.GetProperties();
var dtoType = typeof(T);
IList<PropertyInfo> dtoProperties = dtoType.GetProperties();
var setters = new List<Tuple<int,PropertyInfo>>();
foreach (var dtoProperty in dtoProperties)
{
var indexProperty = indexType.GetProperty(dtoProperty.Name);
var columnIndex = (int) indexProperty.GetValue(index);
setters.Add(Tuple.Create(columnIndex, dtoProperty));
}
foreach (var row in rows)
{
var dto = new T();
foreach (var pair in setters)
{
var colIndex = pair.Item1;
var prop = pair.Item2;
prop.SetValue(dto, row[colIndex]);
}
yield return dto;
}
}
where T : new()
is a generic constraint, to only allow types with parameter-less constructors. It allows you to use new T()
later, without the compiler screaming at you.PropertyInfo.GetValue(object)
and PropertyInfo.SetValue(object, object)
instead of accessing the get- and set-methods directly, since it is easier.