如果我有Type
,是否有一些简单的方法可以告诉它使用Reflection表示可以为空的值类型?理想情况下比(
static bool IsNullable(Type type)
{
return type.IsValueType && type.Name.StartsWith("Nullable");
}
答案 0 :(得分:18)
type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)
您可能还会发现Nullable.GetUnderlyingType(Type nullableType)
有用,可轻松获得您传递的T
typeof(Nullable<T>)
。
答案 1 :(得分:7)
尽管@ theCoop的回答是正确的(在将代码放入你提供的方法的主体中没有从根本上错误的),但这里有一些巨大的问题。
Nullable<T>
被运行时视为具有一些非常特殊语义的“特殊”类型。特别是,当Nullable<T>
装箱时:
HasValue == true
,它的行为就像一个盒装的T
,使得无法通过限制代码来判断创建的对象是否是通过装箱T
或拳击产生的Nullable<T>
。
取消装箱到T
和Nullable<T>
都是可能的。HasValue == false
,拳击只会返回null
。取消装箱到T
将取消,取消装箱到Nullable<T>
将成功,HasValue == false
。 在任何一种情况下,boxedNullableObject.GetType()
都不会显示该对象是通过拳击Nullable<T>.
生成的。我无法想到任何其他表现出这种奇怪行为的值类型。
例如,考虑:
// Output: "System.Nullable`1[System.Int32]"
Console.WriteLine(typeof(int?));
object boxedNullableInt32WithValue = new int?(0);
// Output: "System.Int32", NOT "System.Nullable`1[System.Int32]"
Console.WriteLine(boxedNullableInt32WithValue.GetType());
object boxedNullableInt32WithoutValue = new int?();
// NullReferenceException is thrown
Console.WriteLine(boxedNullableInt32WithoutValue.GetType());
因此,编写如下方法:
public static bool IsObjectANullableT(this object obj) { ... }
是一个非常糟糕的主意。
编辑:另一方面,我刚刚意识到有一种框架方法可以使用与@ theCoop的样本相同的技术来完成您所需的工作:Nullable.GetUnderlyingType
。
用法:
static bool IsNullable(Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
编辑:刚才看到@TheCoop在答案中提到了这一点。我的错误。