Search code examples
c#reflectioninstancegeneric-type-argument

SetValue with generic type T


I have this function: the variable c obtains all the properties of my class <T> in this case:

c ->
Id
Key
Value

public List<T> ReadStoreProceadure<T>(string storeName)
{
    var result = new List<T>();
    var instance = (T) Activator.CreateInstance(typeof (T), new object[] {});
    var c = typeof (T);
    var data = DataReader.ReadStoredProceadures(_factibilidad, storeName); // This part is returning verified data and it's ok

    while (data.Read())
    {
        if (data.HasRows)
        {
            foreach (var item in c.GetProperties())
            {
                //item.SetValue(c, item.Name, null);
            }
        }
    }     
}

How I can add these values to my instance instance and add it to my result variable? It's possible?


Solution

  • I've created an extension method for IDataReader that does essentially what I believe you're trying to do:

    public static List<T> ToList<T>(this IDataReader dr) where T: new()
    {
        var col = new List<T>();
        var type = typeof(T);
        var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
    
        while (dr.Read())
        {
            var obj = new T();
            for (int i = 0; i < dr.FieldCount; i++)
            {
                string fieldName = dr.GetName(i);
                var prop = props.FirstOrDefault(x => x.Name.ToLower() == fieldName.ToLower());
                if (prop != null)
                {
                    if (dr[i] != DBNull.Value)
                    {
                        prop.SetValue(obj, dr[i], null);
                    }
                }
            }
            col.Add(obj);
        }
    
        dr.Close();
        return col;
    }
    

    However, you'll notice I've chosen to work the from the other way around. Instead of iterating the type's properties and fetching them from the DataReader, I iterate the DataReader columns and check for a matching property on the type. You should be able to quickly modify this to fit your data retrieval scheme.