通过反射检测可空类型

jus*_*ase 23 c# reflection nullable

令人惊讶的是,以下代码未通过Assert:

int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
Run Code Online (Sandbox Code Playgroud)

所以只是出于好奇,你怎么能确定给定的实例是否是Nullable <>对象?

Jon*_*eet 52

首先,Nullable<T>是一个结构,所以没有这样的对象.你不能调用GetType(),因为它会包装值(此时你要么得到null,因此是一个异常,或者是一个盒装的非可空值,因此不是你想要的类型).

(拳击是在这里弄乱你的断言 - 我会认为IsType接受object.)

您可以使用类型推断来获取变量的类型作为类型参数:

public bool IsNullable<T>(T value)
{
    return Nullable.GetUnderlyingType(typeof(T)) != null;
}
Run Code Online (Sandbox Code Playgroud)

当您在编译时知道确切的类型时,这并不是一个大量的使用,但是它对于泛型有用.(当然,有其他方法可以实现它.)

你的现实生活情况如何?我认为这不是一个这样的断言,因为你在编译时就知道了这个断言.

  • 非常棘手!这似乎做到了。现在我只需要记住为什么我想知道... (2认同)
  • 要查看它是否是任何可空类型,您可以执行以下操作: (type.IsGenericType &amp;&amp; type.GetGenericTypeDefinition().Equals( typeof(Nullable&lt;&gt;) )); (2认同)

hal*_*000 6

我喜欢@jon-skeet 的答案,但它只有在您知道要测试的类型时才有效。在我们的世界中,我们使用反射来打开对​​象并针对正则表达式测试值。

简化适用于任何类型的扩展对我们来说效果更好。

public static bool IsNullable(this Type type)
{
    return Nullable.GetUnderlyingType(type) != null;
}
Run Code Online (Sandbox Code Playgroud)

仿制药是生命的血液,但有时... :)


Vla*_*mir 5

int? i = 0;
var type = TypedReference.GetTargetType(__makeref(i));
var isNullable = type.IsGenericType &&
    type.GetGenericTypeDefinition() == typeof(Nullable<>);
Run Code Online (Sandbox Code Playgroud)