.net 如何判断对象';s类型可为空<;T>;使用反射?
如果我有一个.net 如何判断对象';s类型可为空<;T>;使用反射?,.net,reflection,nullable,.net,Reflection,Nullable,如果我有一个类型,是否有一些简单的方法可以通过反射判断它代表一个可为空的值类型?理想情况下,比以下内容更干净(更正确): type.IsGenericType&&type.GetGenericTypeDefinition()==typeof(可为空) 您还可能会发现Nullable.GetUnderlyingType(Type nullableType)非常有用,可以轻松获得传入的typeof(Nullable)的T。尽管@theCoop的答案是正确的(将他的代码放入您提供的方法体中没有根本错
类型
,是否有一些简单的方法可以通过反射判断它代表一个可为空的值类型?理想情况下,比以下内容更干净(更正确):
type.IsGenericType&&type.GetGenericTypeDefinition()==typeof(可为空)
您还可能会发现
Nullable.GetUnderlyingType(Type nullableType)
非常有用,可以轻松获得传入的typeof(Nullable)
的T
。尽管@theCoop的答案是正确的(将他的代码放入您提供的方法体中没有根本错误),这里有一些巨大的陷阱
Nullable
被运行时视为“特殊”类型,具有一些非常特殊的语义。特别是,当一个可为空的
被装箱时:
HasValue==true
,它的行为就像一个装箱的T
,使得团队代码无法判断创建的对象是通过装箱一个T
还是通过装箱一个null
生成的。
取消装箱到T
和Nullable
都是可能的HasValue==false
,则装箱只会返回null
。取消绑定到T
将抛出,取消绑定到Nullable
将成功,其中HasValue==false
李>
在这两种情况下,boxedNullableObject.GetType()
都不会显示该对象是通过将一个Nullable装箱而生成的。
我想不出任何其他值类型会表现出这种奇怪的行为
例如,考虑:
// 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(此对象对象对象){…}
这真是个坏主意
编辑:另一方面,我刚刚意识到有一个框架方法,它使用与@theCoop的示例相同的技术来实现您所需要的功能:
用法:
static bool IsNullable(Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
编辑:刚才看到@TheCoop在他的回答中也提到了这一点。我的错。太好了!谢谢(我总是忘记反射中的
)这在许多常见情况下都不起作用,因为CLR将可空的视为一种特殊类型。特别是,它被装箱成一个装箱的T
@Ani:你是什么意思?通过T
,我指的是typeof(T)
非常有用和重要的一点。幸运的是,我特别想确定PropertyInfo
的PropertyType
属性是否是某种可为空的类型;在这种情况下,公司的答案非常有效。但你说得对。哈哈,太棒了:你给我指出了你的另一个问题,这个问题涉及到这件事,除了更清晰和详细。对我来说,这是一次多么大的裁员练习啊。一点也不!我不认为这个答案是多余的;它为我在问题中提出的问题的一般解决方案提供了一些非常重要的洞察。我之所以加入这个链接,是因为我觉得它触及了一些相同的问题,对于那些寻求进一步信息的人来说。它也很有用,因为在看到这个之前,我没有看到其他问题。今天我学到了一些新东西
// 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());
static bool IsNullable(Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}