[英]Detecting a Nullable Type via reflection
令人惊讶的是,以下代码未能通过 Assert:
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
因此,出于好奇,您如何确定给定实例是否为 Nullable<> object?
首先, Nullable<T>
是一个结构体,所以没有这样的对象。 您不能调用GetType()
,因为这会装箱该值(此时您要么获得 null 从而导致异常,要么获得装箱的不可为空值,因此不是您想要的类型)。
(拳击在这里弄乱了你的断言 - 我假设IsType
接受object
。)
您可以使用类型推断来获取变量的类型作为类型参数:
public bool IsNullable<T>(T value)
{
return Nullable.GetUnderlyingType(typeof(T)) != null;
}
当您在编译时知道您的示例中的确切类型时,这并不是大量使用,但它对泛型很有用。 (当然,还有其他实现方式。)
你的现实生活是怎样的? 我认为这不是这样的断言,因为您在编译时就知道了这个断言。
我喜欢@jon-skeet 的答案,但它只有在您知道要测试的类型时才有效。 在我们的世界中,我们使用反射来打开对象并针对正则表达式测试值。
简化适用于任何类型的扩展对我们来说效果更好。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
仿制药是生命的血液,但有时... :)
int? i = 0;
var type = TypedReference.GetTargetType(__makeref(i));
var isNullable = type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>);
这是我想出的,因为其他一切似乎都失败了 - 至少在可移植类库/ DotNet Core with >= C# 6
基本上,您扩展泛型 Type Object
和Nullable<T>
并使用与基础类型匹配的静态扩展方法将被调用并优先于泛型T
扩展方法的事实。
public static partial class ObjectExtension
{
public static bool IsNullable<T>(this T self)
{
return false;
}
}
一个用于Nullable<T>
public static partial class NullableExtension
{
public static bool IsNullable<T>(this Nullable<T> self) where T : struct
{
return true;
}
}
使用反射和type.IsGeneric
和type.GetGenericParameters()
在我当前的 .NET 运行时集上不起作用。
Assert
在什么命名空间中?
如您所料,以下返回true
:
int? wtf = 0;
if (typeof(Nullable<int>).IsInstanceOfType(wtf))
{
// Do things
}
尽管值得注意的是typeof(Nullable<int>).IsInstanceOfType(42)
也返回 true - 这是因为此方法接受一个object
,因此被装箱为Nullable<int>
。
它对我有用,也希望对你有用。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
基于弗拉基米尔的回答:
public static class GenericExtensions
{
public static bool IsNullable<T>(this T item) =>
TypedReference.GetTargetType(__makeref(item)).FullName.Contains("System.Nullable");
}
用法:
int? nullableInt = 42;
bool nIntIsNullable = nullableInt.IsNullable();
持续时间:平均机器<2ms。
评论:
Contains("System.Nullable")
可以更具体。这对我有用,可以检查类型是否为 Nullable..
type.Assembly.FullName.StartsWith("System") && type.Name.Contains("Nullable");
只有这种方式适用于我使用 .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.