您如何处理对象类型切换?
在 C# 中,这个问题时不时就会出现。通常我会得到一个对象值,然后我必须为其调用“真实”函数。像这样的事情:
if (type==typeof(byte))
val = rs.GetByte(col);
else if (type==typeof(int))
val = rs.GetInt32(col);
...
或者
if (type==typeof(byte))
Call((byte)val);
else if (type==typeof(int))
Call((int)val);
...
我可以在这里看到文本模式,但我没有想出可以一次性处理所有肮脏工作的解决方案。
你如何处理它?</strong>你收到对象值,你必须设置它或传递它,但不是作为对象而是作为具体类型(POD、可为空的 POD 和字符串)并且......?
编辑
完整示例(这是问题的原因):
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;
}
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...?
Edits
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用策略模式。只需将每种类型的策略放入哈希表中,然后就不需要开关了。但是,每个策略都需要一个类。如果您有复杂的逻辑,它尤其有用。
如果逻辑相当简单,您也可以使用包含委托的哈希表。
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.
您可以使用 is 运算符对其进行一些清理:
You could clean it up a bit using the is operator: