通过反射检测可空类型
令人惊讶的是,以下代码断言失败:
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
出于好奇,如何确定给定实例是否为 Nullable<>反对与否?
Surprisingly the following code fails the Assert:
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
So just out curiosity, how can you determine if a given instance is a Nullable<> object or not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
首先,
Nullable
是一个结构体,因此不存在这样的对象。您不能调用GetType()
,因为这会将值装箱(此时您要么得到 null,从而出现异常,要么得到装箱的不可空值,因此不是您想要的类型) 。(装箱是这里搞乱你的断言的原因 - 我假设
IsType
接受object
。)不过,你可以使用类型推断来获取 变量的类型< /em> 作为类型参数:
当您在编译时知道确切的类型(如示例中所示)时,这并不是一个很大的用途,但它对于泛型很有用。 (当然,还有其他实现方法。)
您的现实生活情况是什么?我认为这不是这样的断言,因为您在编译时就知道这个断言的答案。
Well firstly,
Nullable<T>
is a struct, so there isn't an object as such. You can't callGetType()
, as that will box the value (at which point you either get null and thus an exception, or a boxed non-nullable value and therefore not the type you want).(Boxing is what's messing up your assertion here - I would assume that
IsType
acceptsobject
.)You can use type inference though to get the type of the variable as a type parameter:
That's not a huge amount of use when you know the exact type at compile-time as in your example, but it's useful for generics. (There are alternative ways of implementing it, of course.)
What's your real life situation? I assume it's not an assertion like this, given that you know the answer to this one at compile time.
我喜欢@jon-skeet 的答案,但只有当你知道你正在测试的类型时它才有效。在我们的世界中,我们使用反射来打开对象并根据正则表达式测试值。
简化扩展以适用于任何类型对我们来说效果更好。
仿制药是生命的血液,但有时......:)
I like the @jon-skeet answer but it only works if you know the type you are testing against. In our world we are using reflection to open up objects and test values against regex expressions.
simplifying the extension to work for any type worked better for us.
generics are life's blood but sometimes... :)
只有这种方法适用于我使用 .net core 7 的情况
Only this way worked in my case using .net core 7
Assert
位于哪个命名空间?正如您所期望的,以下内容返回
true
:尽管值得注意的是
typeof(Nullable).IsInstanceOfType(42)
也返回 true - 这是因为此方法接受一个对象
,因此被装箱为Nullable
。What namespace is
Assert
in?The following returns
true
as you would expect:Although its worth noting that
typeof(Nullable<int>).IsInstanceOfType(42)
also returns true - this is because this method accepts anobject
and so gets boxed as aNullable<int>
.这是我想到的,因为其他一切似乎都失败了 - 至少在 可移植类库 / DotNet Core 上 >= C# 6
基本上你扩展了通用类型 < code>Object 和
Nullable
并使用以下事实:将调用与基础类型匹配的静态扩展方法,并优先于泛型T 扩展方法。
一个用于
Nullable
使用反射和
type.IsGeneric
和type.GetGenericParameters()
在我当前的 .NET 集合上不起作用运行时。Here is what I came up with, as everything else seemed to fail - at least on Portable Class Library / DotNet Core with >= C# 6
Basically you extend generic Type
Object
andNullable<T>
and use the fact that the static extension method that matches the underlying type is going to be invoked and takes precedence over the genericT
extension-method.and one for
Nullable<T>
Using Reflection and
type.IsGeneric
andtype.GetGenericParameters()
did not work on my current set of .NET Runtimes.这对我有用,希望对你也有用。
It works fo me, hope for you too.
基于 Vladimir 答案:
用法:
持续时间:平均机器上 <2 毫秒。
备注:
Contains("System.Nullable")
可以更具体。Based on Vladimir answer:
Usage:
Duration: <2ms on average machine.
Remarks:
Contains("System.Nullable")
can be more specific.这对我来说可以检查类型是否可为空。
This works for me to check wether a type is Nullable or not..