将泛型类与 SqlDataReader GetValue 一起使用
本文关键字:一起 GetValue SqlDataReader 泛型类 | 更新日期: 2023-09-27 18:30:58
我有这段代码,可以很好地处理没有 NULL 值的数据库
public T GetField<T>(SqlDataReader dr, string fieldName)
{
return (T)dr.GetValue(dr.GetOrdinal(fieldName));
}
然后我想控制 DBNull 值,因为它们已经存在于某些表中,我像这样升级了函数:
public T GetField<T>(SqlDataReader dr, string fieldName) where T : new()
{
var value = dr.GetValue(dr.GetOrdinal(fieldName));
return value is DBNull ? new T() : (T)value;
}
但是现在,我不能要求GetField<string>
因为字符串没有参数为 0 的构造函数。
我尝试创建另一个像抽象函数这样的函数,没有任何限制,只有这样的字符串类型
public string GetField<string>(SqlDataReader dr, string fieldName)
{
var value = dr.GetValue(dr.GetOrdinal(fieldName));
return value is DBNull ? "" : value.ToString();
}
但答案是它们是模棱两可的定义,因为 T 还包括字符串,即使应用了限制。
我可以为每个数据类型创建独立的函数,但我更喜欢抽象解决方案,因为它更简洁。
我错过了什么吗?
谢谢!
最后一个方法将失败,因为它尝试声明一个名为 string
的类型参数。
我建议您添加另一个重载,而不对T
进行约束,但具有默认值:
public T GetField<T>(SqlDataReader dr, string fieldName, T defaultValue)
{
var value = dr.GetValue(dr.GetOrdinal(fieldName));
return value is DBNull ? defaultValue : (T) value;
}
然后你可以称之为:
string x = foo.GetField(reader, "field", "");
。还有一个额外的好处,即该方法不是特定于字符串的。
这里有一种方法:
public T GetField<T>(SqlDataReader dr, string fieldName)
{
var value = dr.GetValue(dr.GetOrdinal(fieldName));
return value is DBNull ? default(T) : (T) value;
}
这具有使用可为 null 类型的额外好处。然后你可以称之为:
string x = foo.GetField<string>(reader, "field") ?? "";
在这种情况下,这是故意设计的 - 如果通常你想要null
返回以外的其他东西,那么带有默认值的 Jon 版本更适合您。