[英]Detecting a Nullable Type via reflection
Surprisingly the following code fails the Assert:令人惊讶的是,以下代码未能通过 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?因此,出于好奇,您如何确定给定实例是否为 Nullable<> object?
Well firstly, Nullable<T>
is a struct, so there isn't an object as such.首先, Nullable<T>
是一个结构体,所以没有这样的对象。 You can't call GetType()
, 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).您不能调用GetType()
,因为这会装箱该值(此时您要么获得 null 从而导致异常,要么获得装箱的不可为空值,因此不是您想要的类型)。
(Boxing is what's messing up your assertion here - I would assume that IsType
accepts object
.) (拳击在这里弄乱了你的断言 - 我假设IsType
接受object
。)
You can use type inference though to get the type of the variable as a type parameter:您可以使用类型推断来获取变量的类型作为类型参数:
public bool IsNullable<T>(T value)
{
return Nullable.GetUnderlyingType(typeof(T)) != null;
}
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.我认为这不是这样的断言,因为您在编译时就知道了这个断言。
I like the @jon-skeet answer but it only works if you know the type you are testing against.我喜欢@jon-skeet 的答案,但它只有在您知道要测试的类型时才有效。 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.简化适用于任何类型的扩展对我们来说效果更好。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
generics are life's blood but sometimes... :)仿制药是生命的血液,但有时... :)
int? i = 0;
var type = TypedReference.GetTargetType(__makeref(i));
var isNullable = type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>);
Here is what I came up with, as everything else seemed to fail - at least on Portable Class Library / DotNet Core with >= C# 6这是我想出的,因为其他一切似乎都失败了 - 至少在可移植类库/ DotNet Core with >= C# 6
Basically you extend generic Type Object
and Nullable<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 generic T
extension-method.基本上,您扩展泛型 Type Object
和Nullable<T>
并使用与基础类型匹配的静态扩展方法将被调用并优先于泛型T
扩展方法的事实。
public static partial class ObjectExtension
{
public static bool IsNullable<T>(this T self)
{
return false;
}
}
and one for Nullable<T>
一个用于Nullable<T>
public static partial class NullableExtension
{
public static bool IsNullable<T>(this Nullable<T> self) where T : struct
{
return true;
}
}
Using Reflection and type.IsGeneric
and type.GetGenericParameters()
did not work on my current set of .NET Runtimes.使用反射和type.IsGeneric
和type.GetGenericParameters()
在我当前的 .NET 运行时集上不起作用。
What namespace is Assert
in? Assert
在什么命名空间中?
The following returns true
as you would expect:如您所料,以下返回true
:
int? wtf = 0;
if (typeof(Nullable<int>).IsInstanceOfType(wtf))
{
// Do things
}
Although its worth noting that typeof(Nullable<int>).IsInstanceOfType(42)
also returns true - this is because this method accepts an object
and so gets boxed as a Nullable<int>
.尽管值得注意的是typeof(Nullable<int>).IsInstanceOfType(42)
也返回 true - 这是因为此方法接受一个object
,因此被装箱为Nullable<int>
。
It works fo me, hope for you too.它对我有用,也希望对你有用。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
Based on Vladimir answer :基于弗拉基米尔的回答:
public static class GenericExtensions
{
public static bool IsNullable<T>(this T item) =>
TypedReference.GetTargetType(__makeref(item)).FullName.Contains("System.Nullable");
}
Usage:用法:
int? nullableInt = 42;
bool nIntIsNullable = nullableInt.IsNullable();
Duration: <2ms on average machine.持续时间:平均机器<2ms。
Remarks:评论:
Contains("System.Nullable")
can be more specific. Contains("System.Nullable")
可以更具体。This works for me to check wether a type is Nullable or not..这对我有用,可以检查类型是否为 Nullable..
type.Assembly.FullName.StartsWith("System") && type.Name.Contains("Nullable");
Only this way worked in my case using .net core 7只有这种方式适用于我使用 .net core 7 的情况
bool isNullable = propertyInfo.GetMethod is null ? false : new NullabilityInfoContext().Create(propertyInfo.GetMethod.ReturnParameter).ReadState == NullabilityState.Nullable;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.