猿问

是否可以将null类型用作通用参数?

我想做这样的事情:


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”


是否可以将可空类型指定为通用参数?


幕布斯7119047
浏览 516回答 3
3回答

侃侃无极

仅用于教育目的。:)詹姆斯·琼斯(James Jones)的解决方案可能是这里最好的解决方案,当然也是我会选择的解决方案。C#4.0的dynamic关键字使此操作更容易,即使不太安全:public static dynamic GetNullableValue(this IDataRecord record, string columnName){&nbsp; var val = reader[columnName];&nbsp; 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:警告编码器。
随时随地看视频慕课网APP
我要回答