为什么不能将通用类型转换为null?

时间:2019-11-29 23:13:00

标签: c# .net generics null nullable

A similar question,但不强制转换T参数。

这不起作用

public T GetValueG<T>(string Query)
{
    object value = DBNull.Value;    // Read from Database which can return DBNull
    if (value is DBNull)
        return (T)null;
    else
        return (T)value;
}
  

错误CS0037无法将null转换为'T',因为它是不可为null的值类型


但这可行

public T GetValueG<T>(string Query)
{
    object value = DBNull.Value;    // Read from Database which can return DBNull
    if (value is DBNull)
        value = null;

    return (T)value;
}

我知道使用约束类型where T: struct将使T能够直接转换为null。

但是在第二种方法中,为什么它接受100%可以为null的对象?为什么在没有对象或东西的情况下也不能直接返回null?

1 个答案:

答案 0 :(得分:1)

您尝试做的是错误的。整数是不可为null的类型,这意味着您不能将null作为int的值或任何其他不可为null的类型返回(如名称所示)。

例如:

int myInt = null;-您的IDE会立即将其标记为整数,它是不可为null的类型。

您想要做的是使用您尝试使用的实际类型的可为空类型。 int?bool?

您应该返回nulldefault(T)而不是没有意义的(T)null,因为您不能将null转换为例如一个类类型,它将抛出Object Reference Not Set To An Instance...

我会将您的功能更改为以下内容:

public T GetValueG<T>(string Query)
{

    object value = DBNull.Value;    // Read from Database which can return DBNull
    if (value is DBNull)
        return default(T);  // `return default;` also valid since C# 7.1 

    return (T)value;
}

如果数据库中的值可以为null,则您的模型应实现该类型的nullable,以避免以后产生异常。

您的函数应这样调用GetValueG<int?>("<query>");

非空值的默认值可以在here中找到。

在您的代码中,您将执行myInt == null,而不是使用myNullableInt.HasValue检查空值。

摘要

  

默认关键字。默认情况下将为可空类型返回null。   以及其他非空类型的默认值。根据OP的需要。

default(bool?)->空

default(bool)->假