Auto-populating object properties with Reflection

(Using C# .NET, SQL and Hashtables)

It can be particularly cumbersome setting properties in an object, especially if there are a lot of them, and you want to add/remove/change properties over time.

We can use key/value pairs in a Hashtable to populate an object's properties "automatically" by using reflection and some consistent naming of properties and variables.

Specifically, in this example, we will use SQL query field naming (e.g. "SELECT field1 AS Name") to populate a Hashtable, which is then sent to an object's constructor, and the constructor "self populates" its own properties.

The class object

Let's use a simple person class...

public class Person {
public string Name { get; set; }
public int Age { get; set; }
public bool IsMale { get; set; }

public Person() {
// default constructor
}
}

Nothing exciting there. However, if we want to pass through a list of key/value pairs (of an unspecified length) to automatically assign properties, we need a second constructor. This constructor is going to take a single argument - a Hashtable.

public Person(Hastable ht_Options)
{
Type MyType = this.GetType();
PropertyInfo[] a_Properties = MyType.GetProperties();

foreach (string s_Key in ht_Options.Keys)
{
PropertyInfo pi = a_Properties.Single(item => item.Name == s_Key);

Type t = pi.PropertyType;

if (pi.PropertyType == typeof(System.Int32))
{
pi.SetValue(this, int.Parse(ht_Options[s_Key].ToString()), null);
}

else if (pi.PropertyType == typeof(System.Boolean))
{
pi.SetValue(this, bool.Parse(ht_Options[s_Key].ToString()), null);
}

else
{
pi.SetValue(this, ht_Options[s_Key], null);
}
}
}

When we pass a Hastable to create a new Person object, the constructor will loop through each property (via Reflection) and look for that property name in the Hashtable (by comparing the property names with the Hashtable keys); if the property is an integer or boolean, it will provide the relevant casting.

Obviously there could be a good deal more validation here, but it serves the purpose of demonstration.

Getting our data

If we assume that we want to populate a number of Person objects from some pre-existing data (from, say, a database), we can use SQL named parameters:

SELECT name [Name], age [Age], gender [Gender] FROM people

We can then pass this query to a SqlDataREader object, and loop through each row, adding the name of the column and the value for each row in the query result set.

using (SqlDataReader _reader = _com.ExecuteReader())
{
if (_reader.HasRows)
{
while (_reader.Read())
{
Hashtable ht_Options = new Hashtable();

for (int i = 0; i < _reader.FieldCount; i++)
{
string s_Key = _reader.GetName(i);
string s_KeyValue = _reader[i].ToString();

if (s_Key == "Gender" && s_KeyValue == "Male")
s_KeyValue = "true";

ht_Options.Add(s_Key, s_KeyValue);

} // reader loop

Person p = new Person(ht_Options);

} // reader read
} // has rows
} // execute reader

Such that we now have several Person objects with "automatically" populated properties.