令人惊讶的是,以下代码未通过Assert:
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
所以只是出于好奇,你怎么能确定给定的实例是否是Nullable&lt;&gt;对象与否?
答案 0 :(得分:49)
首先,Nullable<T>
是一个结构,因此没有对象。你不能调用GetType()
,因为它会设置值(此时你得到null,因此是一个异常,或者是一个盒装的非可空值,因此不是你想要的类型)。
(拳击是在这里弄乱你的断言 - 我认为IsType
接受object
。)
您可以使用类型推断来获取变量的类型作为类型参数:
public bool IsNullable<T>(T value)
{
return Nullable.GetUnderlyingType(typeof(T)) != null;
}
当您在编译时知道确切的类型时,这并不是一个很大的用途,但是它对于泛型有用。 (当然,还有其他实现方法。)
你的现实生活情况如何?我认为这不是这样的断言,因为你在编译时就知道了这个断言。
答案 1 :(得分:3)
int? i = 0;
var type = TypedReference.GetTargetType(__makeref(i));
var isNullable = type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>);
答案 2 :(得分:3)
我喜欢@ jon-skeet的答案,但它只有在你知道你正在测试的类型时才有效。在我们的世界中,我们使用反射打开对象并针对正则表达式测试值。
简化扩展以适用于任何类型的扩展工作。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
仿制药是生命的血液,但有时......:)
答案 3 :(得分:0)
Assert
中的名称空间是什么?
以下按照您的预期返回true
:
int? wtf = 0;
if (typeof(Nullable<int>).IsInstanceOfType(wtf))
{
// Do things
}
虽然值得注意的是typeof(Nullable<int>).IsInstanceOfType(42)
也返回true - 这是因为此方法接受object
,因此将其装箱为Nullable<int>
。
答案 4 :(得分:0)
这是我提出的,因为其他一切似乎都失败了 - 至少在可移植类库 / DotNet Core 上使用&gt; = C#6
基本上,您扩展泛型类型Object
和Nullable<T>
,并使用与基础类型匹配的静态扩展方法将被调用并优先于通用T
扩展的事实-method。
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;
}
}
使用Reflection和type.IsGeneric
和type.GetGenericParameters()
在我当前的.NET运行时集上不起作用。
答案 5 :(得分:0)
它对我有用,希望对你也有用。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}