Reputation: 21062
In C# from time to time the issue creeps out. Usually I get an object value and then I have to call "real" function for it. Something like this:
if (type==typeof(byte))
val = rs.GetByte(col);
else if (type==typeof(int))
val = rs.GetInt32(col);
...
or
if (type==typeof(byte))
Call((byte)val);
else if (type==typeof(int))
Call((int)val);
...
I can see a textual pattern here, but I didn't come up with solution which would deal once for good with all the dirty work.
How do you deal it? You receive the object value and you have to either set it or pass it but not as an object but concrete type (PODs, Nullable of PODs and string) and...?
Complete example (this one is the cause of the question):
protected IRecord ReadRecord()
{
if (!ResultSet.Read())
return null;
IRecord record = CreateIRecord();
var type = record.GetType();
int column = -1;
foreach (var prop in type.GetProperties())
{
++column;
object val;
if (prop.PropertyType == typeof(byte))
val = ResultSet.GetByte(column);
else if (prop.PropertyType == typeof(byte?))
val = ResultSet.GetSqlByte(column).ToNullable();
else if (prop.PropertyType == typeof(int))
val = ResultSet.GetInt32(column);
else if (prop.PropertyType == typeof(int?))
val = ResultSet.GetSqlInt32(column).ToNullable();
else if (prop.PropertyType == typeof(double))
val = ResultSet.GetDouble(column);
else if (prop.PropertyType == typeof(double?))
val = ResultSet.GetSqlDouble(column).ToNullable();
else if (prop.PropertyType == typeof(DateTime))
val = ResultSet.GetDateTime(column);
else if (prop.PropertyType == typeof(DateTime?))
val = ResultSet.GetSqlDateTime(column).ToNullable();
else if (prop.PropertyType == typeof(string))
val = ResultSet.GetString(column);
else
throw new ArgumentException("Invalid property type {0}".Expand(prop.PropertyType.ToString()));
prop.SetValue(record, val, null);
}
return record;
}
Upvotes: 1
Views: 201
Reputation: 3160
You could use a strategy pattern. Just put the strategies for each type in a hashtable and then you don't need the switches. However, you'll need one class per strategy. It is especially useful if you have complex logic.
If the logic is rather simple you could also use a Hashtable containing delegates.
//pseudo code
handlers.put(typeof(int), delegate(object value) { return something.GetInt32(value); });
//like this
var handler = handlers[type];
handler.Invoke(val);
Upvotes: 2
Reputation: 20620
You could clean it up a bit using the is operator:
if (MyType is BaseType)...
Upvotes: 2