我想做这样的事情:myYear = record.GetValueOrNull<int?>("myYear"),请注意,可为null的类型为通用参数。由于GetValueOrNull函数可以返回null,所以我的第一个尝试是:public static T GetValueOrNull<T>(this DbDataRecord reader, string columnName) where T : class{ object columnValue = reader[columnName]; if (!(columnValue is DBNull)) { return (T)columnValue; } return null;}但是我现在得到的错误是:类型“ int?” 必须是引用类型,才能在通用类型或方法中将其用作参数“ T”对!Nullable<int>是一个struct!因此,我尝试将类约束更改为struct约束(并且副作用无法再返回null):public static T GetValueOrNull<T>(this DbDataRecord reader, string columnName) where T : struct现在分配:myYear = record.GetValueOrNull<int?>("myYear");给出以下错误:类型“ int?” 必须是非空值类型,才能在通用类型或方法中将其用作参数“ T”是否可以将可空类型指定为通用参数?
3 回答
侃侃无极
TA贡献2051条经验 获得超10个赞
仅用于教育目的。:)詹姆斯·琼斯(James Jones)的解决方案可能是这里最好的解决方案,当然也是我会选择的解决方案。
C#4.0的dynamic关键字使此操作更容易,即使不太安全:
public static dynamic GetNullableValue(this IDataRecord record, string columnName)
{
var val = reader[columnName];
return (val == DBNull.Value ? null : val);
}
现在,您不需要RHS上的显式类型提示:
int? value = myDataReader.GetNullableValue("MyColumnName");
实际上,您甚至根本不需要它!
var value = myDataReader.GetNullableValue("MyColumnName");
value 现在将是一个int或一个字符串,或从数据库返回的任何类型。
唯一的问题是,这不会阻止您在LHS上使用不可为null的类型,在这种情况下,您将获得一个非常讨厌的运行时异常,例如:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot convert null to 'int' because it is a non-nullable value type
与所有使用的代码一样dynamic:警告编码器。
- 3 回答
- 0 关注
- 515 浏览
添加回答
举报
0/150
提交
取消