如何将一个非可空类型转换为可空类型?

6

在运行时,是否有可能将只能确定为非空的值类型转换为可空类型?换句话说:

public Type GetNullableType(Type t)
{
    if (t.IsValueType)
    {
        return typeof(Nullable<t>);
    }
    else
    {
        throw new ArgumentException();
    }
}

显然,return行会出现错误。有没有办法解决这个问题?Type.MakeGenericType方法似乎很有希望,但我不知道如何获取表示Nullable<T>的未指定泛型Type对象。有什么想法吗?

4个回答

12

你想要知道 typeof(Nullable<>).MakeGenericType(t) 的含义。

注意:没有提供任何参数的 Nullable<> 是未绑定的泛型类型;对于更复杂的示例,你需要添加逗号来适应 - 例如 KeyValuePair<,>Tuple<,,,> 等。


谢谢!我搜索了整个typeof()文档,但没有找到有关泛型的任何内容。 - jjoelson
2
@jjoelson - 注意你还应该检查底层类型,因为你不能创建Nullable<Nullable<int>>等-考虑:如果t == typeof(float?)(它具有.ValueType === true), 该怎么办? - Marc Gravell

5

你走在正确的道路上了。试试这个:

if (t.IsValueType)
{
    return typeof(Nullable<>).MakeGenericType(t);
}
else
{
    throw new ArgumentException();
}

2
Type GetNullableType(Type type) {
    // Use Nullable.GetUnderlyingType() to remove the Nullable<T> wrapper
    // if type is already nullable.
    type = Nullable.GetUnderlyingType(type);
    if (type.IsValueType)
        return typeof(Nullable<>).MakeGenericType(type);
    else
        return type;
} 

你能否正确格式化它?缩进文本4个字符以获取代码识别等。 - Marc Gravell
1
这实际上并不是我们在这里想要的,因为传入 typeof(int) 会抛出一个异常(Nullable.GetUnderlyingType(type) 将返回 null)。 - Marc Gravell

0
最简单的解决方案是返回GenericTypeArguments中第一个类型参数的UnderlyingSystemType。因此,在这个例子中,Nullable Datetime?作为属性类型返回,我需要将其转换为Datetime类型,以便将其添加到DataTable中。这应该适用于int?和double?等类型。
if (Nullable.GetUnderlyingType(prop.PropertyType) != null) {
  tb.Columns.Add(prop.Name, prop.PropertyType.GenericTypeArguments.First().UnderlyingSystemType);
} else {
  tb.Columns.Add(prop.Name, prop.PropertyType);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接