令人惊讶的是下面的代码失败的断言:通过反射检测可空类型
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
所以只是出于好奇,你怎么能确定给定的情况下是可空<>对象或没有?
令人惊讶的是下面的代码失败的断言:通过反射检测可空类型
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
所以只是出于好奇,你怎么能确定给定的情况下是可空<>对象或没有?
那么首先,Nullable<T>
是一个结构体,所以没有这样的对象对象。你不能调用GetType()
,因为这会填充值(在这一点上你得到空值,因此是一个例外,或一个盒装非空值,因此不是你想要的类型)。
(拳击是怎么在这里搞乱你的断言 - 我会假设,IsType
接受object
。)
您可以使用类型推断,虽然得到变量的类型作为类型参数:
public bool IsNullable<T>(T value)
{
return Nullable.GetUnderlyingType(typeof(T)) != null;
}
当你在编译时知道确切的类型时,这不是一个巨大的使用量,就像在你的例子中那样,但它对泛型很有用。 (当然,还有其他的实现方法)。
你的真实生活情况如何?我认为这不是一个这样的断言,因为你在编译时知道这个答案。
非常棘手!似乎这样做。现在我只需要记住为什么我想知道那个...... – 2011-05-17 06:14:02
另外我从来没有意识到结构体没有GetType(),但是我应该明白这一点,因为我明白它们被装箱得到这样的东西。 – 2011-05-17 06:15:00
@ justin.m.chase: - 而是因为调用非虚,他们不能重写* *它,这意味着该值始终装箱......然后螺丝事情的Structs从'object'继承'GetType'当原始值可以为空时启动。 – 2011-05-17 06:17:14
什么命名空间是Assert
in?
下返回true
如你所愿:
int? wtf = 0;
if (typeof(Nullable<int>).IsInstanceOfType(wtf))
{
// Do things
}
虽然它值得注意的是,typeof(Nullable<int>).IsInstanceOfType(42)
也返回true - 这是因为该方法接受一个object
等被盒装的Nullable<int>
。
断言是xUnit的,但我只是想在一般的说,该声明应该会成功。 – 2011-05-17 06:08:32
另外,我不认为上述作品......嗯技术上它返回true,但我相信这是一个假阳性,因为这也将返回true:typeof运算(可空
@Kragen:用试试吧' int wtf = 0;'和'int? wtf = null;'一些令人惊讶的结果。拳击使得这种方法签名无法真正做到你想要的。编辑:在你编辑之后,仍然有一个问题 - '42'' *不会*作为'Nullable
int? i = 0;
var type = TypedReference.GetTargetType(__makeref(i));
var isNullable = type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>);
这是辉煌的,它给出了声明的类型(不像'object i = 0; i.GetType()== typeof(int);'')中的底层类型。但是如果要获得声明类型,为什么不简单地使我们的类型推断?就像'public Type GetDeclaredType
这里是我想出了,周围的一切似乎失败 - 至少在便携式类库/DOTNET的核心与> = C#6
基本上你扩展泛型类型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运行时的工作。
我喜欢@ jon-spectet答案,但它只适用于你知道你正在测试的类型。在我们的世界中,我们使用反射来打开对象,并根据正则表达式测试值。
简化任何类型的扩展工作对我们来说都更好。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
泛型是生命的血液,但有时... :)
的可能重复[如何检查对象是否为空?](http://stackoverflow.com/questions/374651/how-检查对象是否可为空) – nawfal 2013-10-10 07:07:12